Alembic - L'utilisation de clés primaires composites entraîne une définition de table incorrecte dans MySQL
P粉183077097
P粉183077097 2023-07-24 22:17:01
0
1
636
<p>J'ai plusieurs modèles de base de données SQLAlchemy "versionnés" qui utilisent des clés primaires composites, obtenues en combinant un champ entier à incrémentation automatique ("id") et un champ datetime ("record_valid_from"). J'essaie d'exécuter ce modèle dans un conteneur Docker local sur une base de données MySQL. </p><p>La définition du modèle est à peu près la suivante :</p><p><br /></p> <pre class="brush:php;toolbar:false;">à partir de l'importation sqlalchemy.orm (DeclarativeBase, mappé) classe classeA (DeclarativeBase) : identifiant : Mapped[int] = mapped_column(primary_key=True, index=True, autoincrement=True) record_valid_from : Mapped[datetime] = mapped_column(DateTime, clé_primaire=Vrai, default=get_current_timestamp # c'est une méthode python renvoyant datetime.now() ) actif : Mapped[bool] = mapped_column(Boolean, par défaut=True, comment="VRAI si dernière version, FALSE sinon" ) ... # quelques champs et logiques supplémentaires</pre> <p>D'autres modèles se ressemblent, avec diverses relations entre eux. </p><p>Lors de l'utilisation d'Alembic pour générer automatiquement des scripts de migration (révision alambic --autogenerate -m "init database"), le code Python généré semble produire des instructions SQL non valides. </p><p>Plus précisément, j'ai rencontré : </p><p><br /></p> <pre class="brush:php;toolbar:false;">(pymysql.err.OperationalError) (1075, 'Définition de table incorrecte ; il ne peut y avoir qu'une seule colonne automatique et elle doit être définie comme une clé')< ;/pré> <p>Voici le code de migration (note : je l'ai simplifié) : </p> <pre class="brush:php;toolbar:false;">def update() -> op.create_table('classA', sa.Column('nom', sa.String(longueur=100), nullable=False), sa.Column('record_valid_from', sa.DateTime(), nullable=False), sa.Column('actif', sa.Boolean(), nullable=False), sa.Column('id', sa.Integer(), autoincrement=True, nullable=False), sa.PrimaryKeyConstraint('record_valid_from', 'id') ) op.create_index(op.f('ix_classA_id'), 'classA', ['id'], unique=False)</pre> <p> Quelqu'un a-t-il vécu une situation similaire ? Ou savez-vous comment résoudre ce problème ? </p><p>J'ai essayé ce qui suit : </p><p><br /></p> <ul> <li>Appelez op.create_primary_key après avoir créé la table (voir : https://alembic.sqlalchemy.org/en/latest/ops.html#alembic.operations.Operations.create_primary_key). Résultat : sqlalchemy.exc.OperationalError : (pymysql.err.OperationalError) (1068, 'Plusieurs clés primaires définies').<code></code></li> <li>Supprimez sa.PrimaryKeyConstraint et appelez directement op.create_primary_key. résultat: <ul> <li>La migration a réussi et s’est déroulée normalement. ≪/li> <li>La tentative de création d'un nouveau modèle ORM a entraîné l'erreur suivante : sqlalchemy.exc.OperationalError : (pymysql.err.OperationalError) (1364, "Le champ 'id' n'a pas de valeur par défaut"). <code></code></li> </ul> ≪/li> </ul><p><br /></p>
P粉183077097
P粉183077097

répondre à tous(1)
P粉921165181

J'ai passé quelques heures sur ce problème et je l'ai résolu moi-même. Pour tous ceux qui ont un problème similaire, voici la réponse :

En fait, l'ordre des champs de clé primaire dans PrimaryKeyConstraint a un impact. Mon problème a été résolu en modifiant l'ordre, au lieu d'utiliser sa.PrimaryKeyConstraint('record_valid_from', 'id'), j'ai changé pour sa.PrimaryKeyConstraint("id", "record_valid_from").

J'espère que cela vous aidera.


Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal