Mysql
 sql >> Database >  >> RDS >> Mysql

Impossibile migrare utilizzando ModelState e ProjectState utilizzando l'API di migrazione in Django 3.0.3

Per iniziare, è necessario utilizzare la metaclasse del modello , cioè. ModelBase , e non type :

from django.db.models.base import ModelBase

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

Dopo aver utilizzato la corretta metaclass , probabilmente riceverai una miriade di errori, poiché stai utilizzando molti attributi di classe che ModelBase imposta internamente e non si aspetta che tu configuri te stesso.

Invece di scaricare tutti gli attributi del tuo modello, dovresti impostare solo gli attributi che ModelBase prevede di essere impostato su un modello tradizionale, che include:

  • __module__ e __qualname__
  • campi modello
  • gestori personalizzati o set di query
  • metodi modello
  • modello Meta

Tutto il resto dovrebbe essere omesso.

Ad esempio, se hai un modello simile a questo, nel modulo 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'

La versione dinamica di questi modelli deve essere simile a questa:

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'}),
})

Non capisco lo scopo del tuo codice di migrazione, quindi presumo che sia stato un hack nel tentativo di far funzionare i modelli dinamici, il che significa che probabilmente puoi eliminarlo del tutto e utilizzare il caricatore di migrazione integrato, ovvero:

python3 manage.py makemigrations myapp && python3 manage.py migrate myapp

Non hai familiarità con python metaclasses , ti consiglio di leggerli, poiché è un prerequisito per comprendere il mio codice.