Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Não é possível migrar usando ModelState e ProjectState usando a API de migrações no Django 3.0.3


Para começar, você precisa usar a metaclasse de modelo , ou seja. ModelBase , e não tipo :
from django.db.models.base import ModelBase

model_definition = ModelBase(
    model_item.table_name,
    bases,
    model_config
)

Depois de usar a metaclass adequada , você provavelmente receberá uma infinidade de erros, pois está usando muitos atributos de classe que ModelBase define internamente, e não está esperando que você se defina.

Em vez de descartar todos os atributos que seu modelo possui, você deve definir apenas os atributos que ModelBase espera ser definido em um modelo tradicional, que inclui:
  • __module__ e __qualname__
  • campos de modelo
  • gerenciadores ou conjuntos de consultas personalizados
  • métodos de modelo
  • modelo Meta

Todo o resto deve ser omitido.

Por exemplo, se você tiver um modelo parecido com este, no módulo myapp.models :
class Parent(models.Model):
    name = models.CharField(max_length=45)

class Child(models.Model):
    name = models.CharField(max_length=45)
    parent = models.ForeignKey(Parent, on_delete=models.CASCADE)

class ModelWithMeta(models.Model):
    class Meta:
        db_table = 'some_table'

A versão dinâmica desses modelos precisa ficar assim:
from django.db import models
from django.db.models.base import ModelBase

bases = (models.Model,)

Parent = ModelBase('Parent', bases, {
    '__module__': 'myapp.models',
    '__qualname__': 'Parent',
    'name': models.CharField(max_length=45),
})

Child = ModelBase('Child', bases, {
    '__module__': 'myapp.models',
    '__qualname__': 'Child',
    'name': models.CharField(max_length=45),
    'parent': models.ForeignKey('myapp.Parent', on_delete=models.CASCADE),
})

ModelWithMeta = ModelBase('ModelWithMeta', bases, {
    '__module__': 'myapp.models',
    '__qualname__': 'ModelWithMeta',
    'Meta': type('Meta', (), {'db_table': 'some_table'}),
})

Eu não entendo o propósito do seu código de migração, então vou assumir que foi um hack na tentativa de fazer os modelos dinâmicos funcionarem, o que significa que você provavelmente pode jogá-lo fora e usar o carregador de migração embutido, ou seja:
python3 manage.py makemigrations myapp && python3 manage.py migrate myapp

Se você não estiver familiarizado com python metaclasses , recomendo ler sobre eles, pois é um pré-requisito para entender meu código.