diff --git a/apps/location/transfer.py b/apps/location/transfer.py index 3c9900f4..5bdc6303 100644 --- a/apps/location/transfer.py +++ b/apps/location/transfer.py @@ -107,6 +107,12 @@ card = { "fields": { "name": "name", } + }, + "CityPhotos": { + "key": ("city_id", "id"), + "fields": { + "coordinates": "geometries" + } } } }, diff --git a/apps/transfer/utils.py b/apps/transfer/utils.py index bf1c7395..55783e9c 100644 --- a/apps/transfer/utils.py +++ b/apps/transfer/utils.py @@ -2,8 +2,12 @@ from os.path import exists from importlib.machinery import SourceFileLoader from django.apps import apps from collections import OrderedDict +from django.db.models import OuterRef, Subquery + import transfer.models as legacy_models +# from pprint import pprint as print + def transfer_objects(data_type): models_list = {} @@ -25,8 +29,10 @@ def transfer_objects(data_type): models_list = sort_by_dependencies(models_list) + legacy_objects = OrderedDict() + for model, card in models_list.items(): - transfer_model(model, card) + legacy_objects[model] = get_model_data(model, card) def sort_by_dependencies(data): @@ -53,15 +59,10 @@ def sort_by_dependencies(data): return result -def transfer_model(model, card): - print(f"=================================================\r\n" - f"MODEL: {model}\r\n" - f"=================================================") - try: - app_model = apps.get_model(app_label=card['app_label'], model_name=model) - except LookupError as e: - print(f"ERROR: model {model} from {card['app_label']} can not be loaded: {e}") - return +def get_model_data(model, card): + # print(f"=================================================\r\n" + # f"MODEL: {model}\r\n" + # f"=================================================") card_fields = card['fields'] relations = card_fields['relations'] if 'relations' in card_fields else None @@ -89,22 +90,72 @@ def transfer_model(model, card): legacy_fields.append(legacy_field) elif isinstance(legacy_field, tuple): - """Группа полей""" if isinstance(legacy_field[0], tuple): + """Группа полей""" for legacy_field_group in legacy_field: legacy_fields.append(legacy_field_group[1]) else: + """Одиночное поле""" legacy_fields.append(legacy_field[1]) + #TODO: убрать после совместимости if model != "City": return - print(legacy_fields) - queryset = legacy_model.objects.only(*legacy_fields) - print(queryset) + """Проверяем наличие внешних связей""" if relations: - for relation_table, relation_data in relations.items(): - print(relation_table) - print(relation_data) + queryset = get_relation_data(relations, queryset, fields) + + return get_transfer_data(model, card, queryset) + + +def get_relation_data(relations, queryset, fields): + + # related_legacy_models = [x.related_model._meta.model.__name__ for x in legacy_model._meta.related_objects] + + """Получаем названия внешних зависимостей""" + for relation_table, relation_data in relations.items(): + """Если объекты связаны через ForeignKey, то ничего не надо делать - все аннотации уже подключены""" + + if isinstance(relation_data['key'], tuple): + """Вытаскиваем relation по id""" + try: + child_legacy_model = apps.get_model(app_label="transfer", model_name=relation_table) + except LookupError as e: + raise LookupError(f"ERROR: legacy model {relation_table} can not be loaded: {e}") + + child_table_queryset = child_legacy_model.objects.filter( + city_id=OuterRef('pk') + ).only(*relation_data['fields'].values()) + + queryset = queryset.annotate(**{ + f"{relation_table.lower()}": + Subquery(child_table_queryset) + }) + + return queryset + + +def get_transfer_data(model, card, queryset): + from pprint import pprint as print + + try: + app_model = apps.get_model(app_label=card['app_label'], model_name=model) + except LookupError as e: + print(f"ERROR: model {model} from {card['app_label']} can not be loaded: {e}") + return + + if "fields" not in card or not isinstance(card['fields'], dict) or len(card['fields']) != 1: + raise ValueError("You must set correct fields to transfer") + + for app_field, legacy_field_data in card['fields'].items(): + print(app_field) + print(legacy_field_data) + + print("*************************************************************************") + # print(app_model) + # print("*************************************************************************") + # print(queryset) + return queryset diff --git a/project/settings/base.py b/project/settings/base.py index d717579d..509b9b14 100644 --- a/project/settings/base.py +++ b/project/settings/base.py @@ -152,7 +152,7 @@ DATABASES = { }, 'legacy': { 'ENGINE': 'django.db.backends.mysql', - 'HOST': '172.19.0.1', + 'HOST': '172.23.0.1', 'PORT': 3306, 'NAME': 'dev', 'USER': 'dev',