recherche

Maison  >  Questions et réponses  >  le corps du texte

Impossible d'auto-incrémenter SQLAlchemy dans MySQL

J'utilise MySQL 8.0 et SQLAlchemy. Ma colonne d'identifiant n'augmente pas et je ne comprends pas pourquoi.

Modèle SQLAlchemy :

class Show(db.Model):
    __tablename__ = "shows"

    id = Column(Integer, primary_key=True, index=True)
    name = Column(String)
    type = Column(String)
    status = Column(String)
    episodes = Column(Integer)
    series_entry_id = Column(Integer, ForeignKey("series.id"))
    series_id = Column(Integer, ForeignKey("series.id"))

    lists = relationship("List", secondary=show_list, back_populates="shows")
    recommendations = relationship("Recommendation", backref=backref("shows"))
    user_ratings = relationship("Rating", backref=backref("shows"))
    alt_names = relationship("User", secondary=alt_names, back_populates="alt_show_names")

    series_entry = relationship("Series", foreign_keys=[series_entry_id], uselist=False)
    series = relationship("Series", foreign_keys=[series_id], post_update=True)

Crackez le code :

show = Show(
        name=new_data["title"]["english"],
        type=new_data["format"],
        status=new_data["status"],
        episodes=new_data["episodes"],
    )

    db.session.add(show)
    db.session.commit()

L'erreur originale que j'ai reçue était :

sqlalchemy.exc.DatabaseError: (mysql.connector.errors.DatabaseError) 1364 (HY000): 
Field 'id' doesn't have a default value

Sur la base de cette réponse, j'ai ajouté le paramètre index à ma colonne id et modifié le fichier my.ini pour le sortir du mode STRICT_TRANS_TABLES. La nouvelle erreur est :

sqlalchemy.exc.IntegrityError: (mysql.connector.errors.IntegrityError) 1062 (23000): 
Duplicate entry '0' for key 'shows.PRIMARY'

Toutes les réponses que j'ai trouvées dans ce sujet impliquent AUTO_INCRMENT,但 SQLAlchemy 文档说这应该是这里的默认值,因为它是一个整数主键,没有指定为 false。我确实尝试添加 autoincrement=True juste au cas où, mais lorsque j'essaye de le migrer, l'alambic me dit qu'aucun changement n'a été détecté.

P粉899950720P粉899950720254 Il y a quelques jours331

répondre à tous(1)je répondrai

  • P粉621033928

    P粉6210339282024-03-22 13:25:49

    Des commentaires aux questions :

    Non, c'est exactement comme ça que ça marche. Concrètement, pour un modèle comme celui-ci

    class Account(Base):
        __tablename__ = "account"
        account_number = Column(Integer, primary_key=True)
        customer_name = Column(String(50))
    

    alembic 修订版 --autogenerate générera

    def upgrade():
        # ### commands auto generated by Alembic - please adjust! ###
        op.create_table('account',
        sa.Column('account_number', sa.Integer(), nullable=False),
        sa.Column('customer_name', sa.String(length=50), nullable=True),
        sa.PrimaryKeyConstraint('account_number')
        )
    

    (sans spécifier explicitement autoincrement=)但是当 alembic 升级 head Obtenez SQLAlchemy pour créer réellement la table émise par SQLAlchemy

    CREATE TABLE account (
            account_number INTEGER NOT NULL AUTO_INCREMENT, 
            customer_name VARCHAR(50), 
            PRIMARY KEY (account_number)
    )
    

    Non. Comme indiqué ci-dessus, Alembic gère correctement AUTO_INCRMENT。它没有检测到的是,具有现有表的 ORM 模型的列从 autoincrement=False 更改为 autoincrement=True lorsque la table est créée pour la première fois (et vice versa).

    Il s'agit d'un comportement connu, comme indiqué dans le message de commit ici  :

    "Veuillez noter que cet indicateur prend en charge la modification du statut "d'incrémentation automatique" d'une colonne, car cela n'est pas portable entre les backends

    ."

    MySQL prend en charge la modification de l'attribut AUTO_INCRMENT d'une colonne via ALTER_TABLE, nous pouvons donc le faire en changeant la méthode "null" upgrade

    def upgrade():
        # ### commands auto generated by Alembic - please adjust! ###
        pass
        # ### end Alembic commands ###
    

    à

    def upgrade():
        op.alter_column(
            'account',
            'account_number',
            existing_type=sa.Integer(),
            existing_nullable=False,
            autoincrement=True
        )
    

    Rendu

    ALTER TABLE account MODIFY account_number INTEGER NOT NULL AUTO_INCREMENT
    

    répondre
    0
  • Annulerrépondre