176 lines
5.2 KiB
Python
176 lines
5.2 KiB
Python
from os.path import exists
|
||
from importlib.machinery import SourceFileLoader
|
||
from django.apps import apps
|
||
from collections import OrderedDict
|
||
from pprint import pprint
|
||
|
||
def transfer_objects(data_type):
|
||
models_list = {}
|
||
|
||
for app in apps.get_app_configs():
|
||
if exists(f"{app.path}/transfer.py"):
|
||
card_module = SourceFileLoader("transfer", f"{app.path}/transfer.py").load_module()
|
||
if not hasattr(card_module, "card") or len(card_module.card) < 1:
|
||
continue
|
||
|
||
for model, card in card_module.card.items():
|
||
if "data_type" in card and data_type == card["data_type"]:
|
||
card['app_label'] = app.label
|
||
models_list[model] = card
|
||
|
||
if len(models_list) < 1:
|
||
print(f"Models with data type {data_type} not found in structure")
|
||
exit(1)
|
||
|
||
models_list = sort_by_dependencies(models_list)
|
||
|
||
for model, card in models_list.items():
|
||
transfer_data(model, card)
|
||
|
||
|
||
# TRANSFER DATA FUNCTION
|
||
def transfer_data(model, card):
|
||
legacy_model_queryset = get_legacy_data(card)
|
||
fields_map = get_fields_map(card, legacy_model_queryset)
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
# ************************** UTILITIES ******************************
|
||
|
||
# Get map of fields
|
||
def get_fields_map(card, queryset):
|
||
relations = card['fields']['relations'] if "relations" in card['fields'] else None
|
||
if relations:
|
||
del (card['fields']['relations'])
|
||
|
||
fields_list = list(card['fields'].values())[0]
|
||
|
||
app_queryset_list = []
|
||
|
||
for legacy_object in queryset.iterator():
|
||
app_queryset_dict = {}
|
||
for app_field, legacy_field in fields_list.items():
|
||
if isinstance(legacy_field, tuple):
|
||
if isinstance(legacy_field[0], tuple):
|
||
# Группа полей с аргументами
|
||
pass
|
||
else:
|
||
print(app_field)
|
||
print(legacy_field)
|
||
else:
|
||
try:
|
||
app_queryset_dict[app_field] = getattr(legacy_object, legacy_field)
|
||
except Exception as e:
|
||
print(f"Attribute {legacy_field} not found in {legacy_object}: {e}")
|
||
return
|
||
|
||
app_queryset_list.append(app_queryset_dict)
|
||
|
||
# pprint(card)
|
||
# print("*************************************")
|
||
# pprint(fields_list)
|
||
# print("*************************************")
|
||
# pprint(relations)
|
||
# print("*************************************")
|
||
# pprint(len(queryset))
|
||
print("==============================")
|
||
|
||
return card
|
||
|
||
|
||
# Get legacy model data
|
||
def get_legacy_data(card):
|
||
if "fields" not in card:
|
||
print("You must set fields list")
|
||
return
|
||
card_fields = card['fields']
|
||
relations = card_fields['relations'] if 'relations' in card_fields else None
|
||
|
||
if relations:
|
||
del (card_fields['relations'])
|
||
|
||
if len(card_fields) > 1:
|
||
print("You must set one table to transfer")
|
||
return
|
||
|
||
try:
|
||
legacy_table = list(card_fields.keys())[0]
|
||
except Exception as e:
|
||
print(f"Cannot get legacy table name from {card_fields.keys()}")
|
||
return
|
||
try:
|
||
fields = list(card_fields.values())[0]
|
||
except Exception as e:
|
||
print(f"Cannot get legacy fields from {card_fields.values()}")
|
||
return
|
||
|
||
try:
|
||
legacy_model = apps.get_model(app_label="transfer", model_name=legacy_table)
|
||
except LookupError as e:
|
||
print(f"ERROR: legacy model {legacy_table} can not be loaded: {e}")
|
||
return
|
||
|
||
legacy_fields = []
|
||
|
||
for legacy_field in fields.values():
|
||
if isinstance(legacy_field, str):
|
||
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[0])
|
||
|
||
queryset = legacy_model.objects.only(*legacy_fields)
|
||
|
||
# Возвращаем зависимости на место
|
||
if relations:
|
||
card['fields']['relations'] = relations
|
||
|
||
return queryset
|
||
|
||
|
||
# Models sort
|
||
def sort_by_dependencies(data):
|
||
"""Сортировка моделей по зависимостям"""
|
||
|
||
"""Сначала мы сортируем модели по зависимостям в обратном порядке, используя сортировку вставкой"""
|
||
result = []
|
||
for model, card in data.items():
|
||
if "dependencies" in card and isinstance(card['dependencies'], tuple):
|
||
for model_dependency in result:
|
||
if model_dependency in card['dependencies']:
|
||
result.insert(result.index(model_dependency), model)
|
||
break
|
||
|
||
else:
|
||
result.append(model)
|
||
|
||
"""Затем мы создаём сортированный словарь из реверса получившегося результата"""
|
||
|
||
result = OrderedDict(
|
||
[(model, data[model]) for model in reversed(result)]
|
||
)
|
||
|
||
return result |