Skip to content

Commit

Permalink
Merge branch 'dev' into feature/convert_ci-cd_to_the_prod
Browse files Browse the repository at this point in the history
  • Loading branch information
OlegGsk authored Oct 1, 2024
2 parents ccaef8a + 74e89cf commit 9680c9c
Show file tree
Hide file tree
Showing 34 changed files with 299 additions and 1,791 deletions.
4 changes: 2 additions & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.5.0
rev: v4.6.0
hooks:
- id: check-docstring-first
- id: check-merge-conflict
- id: end-of-file-fixer
- id: trailing-whitespace

- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.4.5
rev: v0.6.8
hooks:
- id: ruff
exclude: migrations/|config/|tests/|.*settings(\.py|/)?
Expand Down
12 changes: 12 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ help:
@echo " run - $(SHELL_GREEN)Команда для локального запуска проекта.$(SHELL_NC)."
@echo " fill-db - $(SHELL_GREEN)Команда для заполнения базы данных реальными данными из json фикстур.$(SHELL_NC)."
@echo " fill-test-db - $(SHELL_GREEN)Команда для заполнения базы данных тестовыми данными при помощи фабрик генерации данных.$(SHELL_NC)."
@echo " export-db - $(SHELL_GREEN)Команда для экспорта данных из БД в JSON файл.$(SHELL_NC)."
@echo " import-db - $(SHELL_GREEN)Команда для импорта данных из JSON файла в БД.$(SHELL_NC)."
@echo " pytest - $(SHELL_GREEN)Команда для прогона юнит тестов pytest.$(SHELL_NC)."
@echo " shell - $(SHELL_GREEN)Команда для запуска Django-shell_plus.$(SHELL_NC)."
@echo " ds-mock - $(SHELL_GREEN)Команда для запуска имитации DS сервера (порт 8010).$(SHELL_NC)."
Expand Down Expand Up @@ -117,6 +119,16 @@ fill-test-db:
cd $(PROJECT_DIR) && $(DJANGO_RUN) fill-test-db --json-player-data --amount 10


# Экспорт данных из бд
export-db:
cd $(DJANGO_DIR) && $(DJANGO_RUN) export-db


# Импорт данных в бд
import-db:
cd $(DJANGO_DIR) && $(DJANGO_RUN) import-db


# Прогон тестов с помощью pytest.
pytest:
cd $(DJANGO_DIR) && pytest
Expand Down
1 change: 0 additions & 1 deletion adaptive_hockey_federation/core/config/base_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@
"analytics.apps.AnalyticsConfig",
"unloads.apps.UnloadsConfig",
"games.apps.GamesConfig",
"video_api.apps.VideoApiConfig",
]

INSTALLED_APPS = EXTERNAL_APPS + DEFAULT_APPS + LOCAL_APPS
Expand Down
5 changes: 4 additions & 1 deletion adaptive_hockey_federation/core/config/dev_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,15 @@
}

DJANGO_SUPERUSER_USERNAME = env("DJANGO_SUPERUSER_USERNAME", default="admin")
DJANGO_SUPERUSER_EMAIL = env("DJANGO_SUPERUSER_EMAIL", default="admin@admin.ru")
DJANGO_SUPERUSER_EMAIL = env(
"DJANGO_SUPERUSER_EMAIL", default="admin@admin.ru"
)
DJANGO_SUPERUSER_PASSWORD = env("DJANGO_SUPERUSER_PASSWORD", default="admin")

FIXSTURES_DIR = BASE_DIR / "core" / "fixtures"
JSON_PARSER_FILE = "data.json"
FIXSTURES_FILE = FIXSTURES_DIR / JSON_PARSER_FILE
DB_DUMP_FILE = FIXSTURES_DIR / "db_dump.json"
RESOURSES_ROOT = BASE_DIR / "resourses"

# Важен порядок ключей для вставки/удаления
Expand Down
32 changes: 32 additions & 0 deletions adaptive_hockey_federation/core/management/commands/export-db.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
from django.core.management import call_command
from django.core.management.base import BaseCommand

from adaptive_hockey_federation.core.config.dev_settings import DB_DUMP_FILE


class Command(BaseCommand):
"""Класс экспорта данных из БД."""

help = "Экспорт данных из базы данных в JSON-файл"

def handle(self, *args, **options):
"""Экспортирует данные из БД."""
try:
call_command(
"dumpdata",
exclude=["contenttypes", "auth.permission"],
natural_foreign=True,
natural_primary=True,
indent=2,
output=DB_DUMP_FILE,
)

return self.stdout.write(
self.style.SUCCESS(
f"База данных экспортирована в {DB_DUMP_FILE}",
),
)
except Exception as e:
return self.stdout.write(
self.style.ERROR(f"Ошибка при экспорте данных: {str(e)}"),
)
155 changes: 106 additions & 49 deletions adaptive_hockey_federation/core/management/commands/fill-db.py
Original file line number Diff line number Diff line change
@@ -1,83 +1,140 @@
import json

from django.apps import apps
from django.core.management.base import BaseCommand
from django.db import connection, transaction
from main.models import Diagnosis

from adaptive_hockey_federation.core.config.dev_settings import (
FILE_MODEL_MAP,
FIXSTURES_DIR,
FIXSTURES_FILE,
)
from adaptive_hockey_federation.parser.importing_db import (
clear_data_db,
importing_parser_data_db,
importing_real_data_db,
)

DB_MESSAGE = "Данные успешно добавлены!"


class Command(BaseCommand):
"""Класс для парсинга данных и их записи в БД."""

help = "Запуск парсера офисных документов, и запись их в БД."

def add_arguments(self, parser):
"""Добавляет новые аргументы для командной строки."""
parser.add_argument(
"-p",
"--parser",
action="store_true",
help="Запуск парсера документов",
)
"""Аргументы."""
parser.add_argument(
"-f",
"--fixtures",
action="store_true",
help="Фикстуры с реальными данными для таблиц.",
)

def load_data(self) -> None:
"""Загрузка распарсенных данных."""
importing_parser_data_db(FIXSTURES_FILE)
return None

def load_real_data(self) -> None:
@transaction.atomic
def load_real_data(self) -> None: # noqa: C901
"""Загрузка реальных данных из JSON."""
for key in FILE_MODEL_MAP.items():
file_name = key[0] + ".json"
if "main_" in key[0]:
with connection.cursor() as cursor:
for table_name in FILE_MODEL_MAP.keys():
try:
clear_data_db(file_name)
cursor.execute(f"TRUNCATE TABLE {table_name} CASCADE")
except Exception as e:
self.stdout.write(
self.style.ERROR(
f"Ошибка удаления данных {e} -> " f"{file_name}",
return self.stdout.write(
self.style.WARNING(
f"Не удалось очистить таблицу {table_name}: {str(e)}", # noqa: E501
),
)

items = list(FILE_MODEL_MAP.items())
items.reverse()
for key in items:
file_name = key[0] + ".json"
if "main_" in key[0]:
try:
importing_real_data_db(FIXSTURES_DIR, file_name)
self.stdout.write(
self.style.SUCCESS(
f"Фикстуры с файла {file_name} вставлены "
"в таблицы!",
),
)
except Exception as e:
return self.stdout.write(
self.style.ERROR_OUTPUT(
f"Ошибка вставки данных {e} -> " f"{file_name}",
),
)
return None
for table_name, model_class in items:
file_path = FIXSTURES_DIR / f"{table_name}.json"
app_label, model_name = table_name.split("_", 1)
model = apps.get_model(app_label, model_name)
try:
with open(file_path, "r", encoding="utf-8") as file:
data = json.load(file)

for item in data:
if table_name == "main_team":
team_data = {
"id": item["id"],
"name": item["name"],
"city_id": item["city_id"],
"discipline_name_id": item["discipline_name_id"],
"curator_id": 1,
}
instance = model(**team_data)
elif table_name == "main_player":
disciplines = self.get_disciplines()
diagnosis = None
if item.get("diagnosis_id"):
try:
diagnosis = Diagnosis.objects.get(
pk=item["diagnosis_id"],
)
except Diagnosis.DoesNotExist:
print(
f"Диагноз с id {item.get('diagnosis_id')} отсутсвует.", # noqa: E501
)
player_data = {
"id": item["id"],
"surname": item["surname"],
"name": item["name"],
"patronymic": item["patronymic"],
"birthday": item["birthday"],
"gender": item["gender"],
"level_revision": item["level_revision"],
"position": item["position"],
"number": item["number"],
"is_captain": item["is_captain"],
"is_assistent": item["is_assistent"],
"identity_document": item["identity_document"],
"diagnosis": diagnosis,
"diagnosis_id": item["diagnosis_id"],
"discipline_name_id": disciplines[
item["discipline_id"]
]["discipline_name_id"],
"discipline_level_id": disciplines[
item["discipline_id"]
]["discipline_level_id"],
}
instance = model(**player_data)
else:
instance = model(**item)
instance.save()

self.stdout.write(
self.style.SUCCESS(
f"Данные из {table_name}.json успешно загружены в модель {model_class}", # noqa: E501
),
)

except FileNotFoundError:
self.stdout.write(
self.style.WARNING(f"Файл {table_name}.json не найден"),
)
except Exception as e:
self.stdout.write(
self.style.ERROR(
f"Ошибка при загрузке данных из {table_name}.json: {str(e)}", # noqa: E501
),
)

def handle(self, *args, **options):
"""Запись данных в БД."""
parser = options.get("parser")
fixtures = options.get("fixtures")
if fixtures:
self.load_real_data()
if parser:
self.load_data()

def get_disciplines(self) -> dict:
"""Получение диспциплин."""
with open(
FIXSTURES_DIR / "main_discipline.json",
"r",
encoding="utf-8",
) as file:
data = json.load(file)
disciplines = {
None: {"discipline_level_id": None, "discipline_name_id": None},
}
for item in data:
disciplines[item["id"]] = {
"discipline_level_id": item["discipline_level_id"],
"discipline_name_id": item["discipline_name_id"],
}
return disciplines
54 changes: 54 additions & 0 deletions adaptive_hockey_federation/core/management/commands/import-db.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import json
import os

from django.apps import apps
from django.core.management import call_command
from django.core.management.base import BaseCommand
from django.db import connection

from adaptive_hockey_federation.core.config.dev_settings import DB_DUMP_FILE


class Command(BaseCommand):
"""Класс импорта данных в БД."""

help = "Импорт данных из JSON-файла в базу данных"

def handle(self, *args, **options):
"""Импортирует данные в БД."""
if not os.path.exists(DB_DUMP_FILE):
return self.stdout.write(
self.style.ERROR(f"Файл {DB_DUMP_FILE} не найден"),
)

with open(DB_DUMP_FILE, "r") as f:
data = json.load(f)
models_to_clear = set(item["model"] for item in data)

# Очистка таблиц, в которые импортируются данные,
# для исключения ошибки unique constraint
with connection.cursor() as cursor:
for model_name in models_to_clear:
try:
app_label, model = model_name.split(".")
model_class = apps.get_model(app_label, model)
table_name = model_class._meta.db_table
cursor.execute(f"TRUNCATE TABLE {table_name} CASCADE")
except Exception as e:
return self.stdout.write(
self.style.WARNING(
f"Не удалось очистить таблицу для модели {model_name}: {str(e)}", # noqa: E501
),
)

try:
call_command("loaddata", DB_DUMP_FILE)
return self.stdout.write(
self.style.SUCCESS(
f"Данные из {DB_DUMP_FILE} импортированы в базу данных",
),
)
except Exception as e:
return self.stdout.write(
self.style.ERROR(f"Ошибка при импорте данных: {str(e)}"),
)
2 changes: 1 addition & 1 deletion adaptive_hockey_federation/core/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@


from core.constants import AgeLimits, FileConstants, TimeFormat
from core.settings.openpyxl_settings import (
from core.config.openpyxl.settings import (
ALIGNMENT_CENTER,
HEADERS_BORDER,
HEADERS_FILL,
Expand Down
Empty file.
Loading

0 comments on commit 9680c9c

Please sign in to comment.