This commit is contained in:
littlewolf 2019-10-11 10:45:49 +03:00
parent 0e474a16ea
commit f5c16fba9d
3 changed files with 75 additions and 18 deletions

View File

@ -107,6 +107,12 @@ card = {
"fields": { "fields": {
"name": "name", "name": "name",
} }
},
"CityPhotos": {
"key": ("city_id", "id"),
"fields": {
"coordinates": "geometries"
}
} }
} }
}, },

View File

@ -2,8 +2,12 @@ from os.path import exists
from importlib.machinery import SourceFileLoader from importlib.machinery import SourceFileLoader
from django.apps import apps from django.apps import apps
from collections import OrderedDict from collections import OrderedDict
from django.db.models import OuterRef, Subquery
import transfer.models as legacy_models import transfer.models as legacy_models
# from pprint import pprint as print
def transfer_objects(data_type): def transfer_objects(data_type):
models_list = {} models_list = {}
@ -25,8 +29,10 @@ def transfer_objects(data_type):
models_list = sort_by_dependencies(models_list) models_list = sort_by_dependencies(models_list)
legacy_objects = OrderedDict()
for model, card in models_list.items(): for model, card in models_list.items():
transfer_model(model, card) legacy_objects[model] = get_model_data(model, card)
def sort_by_dependencies(data): def sort_by_dependencies(data):
@ -53,15 +59,10 @@ def sort_by_dependencies(data):
return result return result
def transfer_model(model, card): def get_model_data(model, card):
print(f"=================================================\r\n" # print(f"=================================================\r\n"
f"MODEL: {model}\r\n" # f"MODEL: {model}\r\n"
f"=================================================") # 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
card_fields = card['fields'] card_fields = card['fields']
relations = card_fields['relations'] if 'relations' in card_fields else None 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) legacy_fields.append(legacy_field)
elif isinstance(legacy_field, tuple): elif isinstance(legacy_field, tuple):
"""Группа полей"""
if isinstance(legacy_field[0], tuple): if isinstance(legacy_field[0], tuple):
"""Группа полей"""
for legacy_field_group in legacy_field: for legacy_field_group in legacy_field:
legacy_fields.append(legacy_field_group[1]) legacy_fields.append(legacy_field_group[1])
else: else:
"""Одиночное поле"""
legacy_fields.append(legacy_field[1]) legacy_fields.append(legacy_field[1])
#TODO: убрать после совместимости
if model != "City": if model != "City":
return return
print(legacy_fields)
queryset = legacy_model.objects.only(*legacy_fields) queryset = legacy_model.objects.only(*legacy_fields)
print(queryset)
"""Проверяем наличие внешних связей"""
if relations: if relations:
for relation_table, relation_data in relations.items(): queryset = get_relation_data(relations, queryset, fields)
print(relation_table)
print(relation_data) 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

View File

@ -152,7 +152,7 @@ DATABASES = {
}, },
'legacy': { 'legacy': {
'ENGINE': 'django.db.backends.mysql', 'ENGINE': 'django.db.backends.mysql',
'HOST': '172.19.0.1', 'HOST': '172.23.0.1',
'PORT': 3306, 'PORT': 3306,
'NAME': 'dev', 'NAME': 'dev',
'USER': 'dev', 'USER': 'dev',