Heim  >  Fragen und Antworten  >  Hauptteil

Alembic – Die Verwendung zusammengesetzter Primärschlüssel führt zu einer falschen Tabellendefinition in MySQL

<p>Ich habe mehrere „versionierte“ SQLAlchemy-Datenbankmodelle, die zusammengesetzte Primärschlüssel verwenden, die durch die Kombination eines automatisch inkrementierenden Ganzzahlfelds („id“) und eines Datums-/Uhrzeitfelds („record_valid_from“) erreicht werden. Ich versuche, dieses Modell in einem lokalen Docker-Container gegen eine MySQL-Datenbank auszuführen. </p><p>Die Modelldefinition lautet ungefähr wie folgt:</p><p><br /></p> <pre class="brush:php;toolbar:false;">from sqlalchemy.orm import (DeclarativeBase, Mapped) Klasse classA(DeclarativeBase): id: Mapped[int] = mapped_column(primary_key=True, index=True, autoincrement=True) record_valid_from: Mapped[datetime] = mapped_column(DateTime, Primary_key=True, default=get_current_timestamp # Dies ist eine Python-Methode, die datetime.now() zurückgibt. ) aktiv: Mapped[bool] = mapped_column(Boolean, default=True, comment="TRUE wenn neueste Version, andernfalls FALSE" ) ... # einige weitere Felder und Logik</pre> <p>Andere Modelle sehen ähnlich aus, es gibt jedoch unterschiedliche Beziehungen zwischen ihnen. </p><p>Bei Verwendung von Alembic zum automatischen Generieren von Migrationsskripten (alembic revision --autogenerate -m "init Database") scheint der generierte Python-Code ungültige SQL-Anweisungen zu erzeugen. </p><p> Genauer gesagt bin ich auf Folgendes gestoßen: </p><p><br /></p> <pre class="brush:php;toolbar:false;">(pymysql.err.OperationalError) (1075, 'Falsche Tabellendefinition; es kann nur eine automatische Spalte geben und diese muss als Schlüssel definiert werden')< ;/pre> <p>Hier ist der Migrationscode (Hinweis: Ich habe ihn vereinfacht): </p> <pre class="brush:php;toolbar:false;">def upgrade() -> op.create_table('classA', sa.Column('name', sa.String(length=100), nullable=False), sa.Column('record_valid_from', sa.DateTime(), nullable=False), sa.Column('active', 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>Hat jemand eine ähnliche Situation erlebt? Oder wissen Sie, wie Sie dieses Problem lösen können? </p><p>Ich habe Folgendes versucht: </p><p><br /></p> <ul> <li>Rufen Sie op.create_primary_key nach dem Erstellen der Tabelle auf (siehe: https://alembic.sqlalchemy.org/en/latest/ops.html#alembic.operations.Operations.create_primary_key). Ergebnis: sqlalchemy.exc.OperationalError: (pymysql.err.OperationalError) (1068, „Mehrere Primärschlüssel definiert“).<code></code></li> <li>sa.PrimaryKeyConstraint entfernen und op.create_primary_key direkt aufrufen. Ergebnis: <ul> <li>Die Migration war erfolgreich und verlief normal. </li> <li>Der Versuch, ein neues ORM-Modell zu erstellen, führte zu folgendem Fehler: sqlalchemy.exc.OperationalError: (pymysql.err.OperationalError) (1364, „Feld ‚id‘ hat keinen Standardwert“). <code></code></li> </ul> </li> </ul><p><br /></p>
P粉183077097P粉183077097476 Tage vor599

Antworte allen(1)Ich werde antworten

  • P粉921165181

    P粉9211651812023-07-25 14:49:14

    我花了几个小时解决了这个问题,并且自己修复了它。对于遇到类似问题的人,这是答案:

    实际上,主键字段在PrimaryKeyConstraint中的顺序是有影响的。我的问题是通过改变顺序来解决的,而不是使用sa.PrimaryKeyConstraint('record_valid_from', 'id'),我改成了sa.PrimaryKeyConstraint("id", "record_valid_from")。

    希望这可以帮到你。


    Antwort
    0
  • StornierenAntwort