Merge remote-tracking branch 'origin/feature/migrate-city-objects' into feature/migrate-city-objects

This commit is contained in:
michail 2019-10-21 17:32:02 +05:00
commit 4d3ecb65f2
2 changed files with 1 additions and 219 deletions

View File

@ -4,6 +4,7 @@ from news.models import NewsType
from django.db.models import Value, IntegerField, F from django.db.models import Value, IntegerField, F
from pprint import pprint from pprint import pprint
def transfer_news(): def transfer_news():
news_type, _ = NewsType.objects.get_or_create(name="News") news_type, _ = NewsType.objects.get_or_create(name="News")

View File

@ -1,9 +1,6 @@
from os.path import exists 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
import importlib
from pprint import pprint
def transfer_objects(data_type): def transfer_objects(data_type):
@ -16,222 +13,6 @@ def transfer_objects(data_type):
for module_data_type, transfer_funcs in card_module.data_types.items(): for module_data_type, transfer_funcs in card_module.data_types.items():
if data_type == module_data_type: if data_type == module_data_type:
# card['app_label'] = app.label
# models_list[model] = card
for transfer_func in transfer_funcs: for transfer_func in transfer_funcs:
print(f"========================== FUNCTION {transfer_func.__name__} ================================") print(f"========================== FUNCTION {transfer_func.__name__} ================================")
transfer_func() transfer_func()
# 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)
print("==============================================================================")
print(model)
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 = []
# print("==============================================================================")
# pprint(card)
# print("==============================================================================")
for legacy_object in queryset.iterator():
app_queryset_dict = {}
for app_field, legacy_field in fields_list.items():
app_value = convert_field_from_legacy_to_app(legacy_object, legacy_field)
if app_value is not None:
app_queryset_dict[app_field] = app_value
if relations is not None:
for relation_table, relation_data in relations.items():
# print(f"{relation_table.lower()}_set")
print(legacy_object.pagetext)
# relation_object = getattr(legacy_object, f"{relation_table.lower()}_set")
# print(relation_object)
print("==============================")
app_queryset_list.append(app_queryset_dict)
return app_queryset_list
# Convert field
def convert_field_from_legacy_to_app(legacy_object, legacy_field):
result = None
if isinstance(legacy_field, tuple):
if isinstance(legacy_field[0], tuple):
# legacy_attributes = {}
# for legacy_attribute in legacy_field:
print(legacy_field)
else:
if hasattr(legacy_object, legacy_field[0]):
try:
legacy_data = getattr(legacy_object, legacy_field[0])
except Exception as e:
raise AttributeError(f"Attribute {legacy_field} not found in {legacy_object}: {e}")
field_module = legacy_field[-1].split(".")
try:
field_type = getattr(importlib.import_module(".".join(field_module[:-1])), field_module[-1])
except Exception as e:
raise ValueError(f"Cannot set new field type for field {legacy_field}: {e}")
if len(legacy_field) == 3:
result = field_type(**{legacy_field[1]: legacy_data})
elif len(legacy_field) == 2:
result = field_type(legacy_data)
else:
print(f"Attribute {legacy_field} not found in {legacy_object.__dict__}")
else:
if hasattr(legacy_object, legacy_field):
result = getattr(legacy_object, legacy_field)
else:
print(f"Attribute {legacy_field} not found in {legacy_object.__dict__}")
return result
# 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.all()[:50]# TODO: remove after debug
# Возвращаем зависимости на место
if relations is not None:
queryset = add_legacy_relation_data(queryset, relations)
card['fields']['relations'] = relations
return queryset
# Add relation data to queryset
def add_legacy_relation_data(queryset, relations):
for relation_table in relations.keys():
queryset = queryset.prefetch_related(relation_table.lower())
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