Mysql
 sql >> Base de données >  >> RDS >> Mysql

Impossible de migrer à l'aide de ModelState et ProjectState à l'aide de l'API de migration dans Django 3.0.3

Pour commencer, vous avez besoin utiliser la métaclasse de modèle , c'est à dire. ModelBase , et non type :

from django.db.models.base import ModelBase

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

Une fois que vous utilisez la bonne métaclasse , vous recevrez probablement une myriade d'erreurs, car vous utilisez de nombreux attributs de classe que ModelBase définit en interne et ne s'attend pas à ce que vous vous définissiez vous-même.

Au lieu de vider tous les attributs de votre modèle, vous ne devez définir que les attributs que ModelBase s'attend à être défini sur un modèle traditionnel, qui comprend :

  • __module__ et __qualname__
  • champs de modèle
  • Gestionnaires personnalisés ou ensembles de requêtes
  • méthodes du modèle
  • modèle Meta

Tout le reste doit être omis.

Ainsi, par exemple, si vous avez un modèle qui ressemble à ceci, dans le module 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 version dynamique de ces modèles doit ressembler à ceci :

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

Je ne comprends pas le but de votre code de migration, donc je supposerai qu'il s'agissait d'un piratage pour tenter de faire fonctionner les modèles dynamiques, ce qui signifie que vous pouvez probablement le jeter complètement et utiliser le chargeur de migration intégré, c'est-à-dire :

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

Si vous n'êtes pas familier avec python metaclasses , je vous recommande de les lire, car c'est un prérequis pour comprendre mon code.