gault-millau/apps/transfer/utils.py
littlewolf 47a4d28cf0 Add fields map for simple field
Add fields map for tuple field
Refactoring code
2019-10-15 12:05:49 +03:00

176 lines
5.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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