web-dev-qa-db-fra.com

impossible de créer la clé primaire à incrémentation automatique avec flask-sqlalchemy

Je veux que la clé primaire de mon modèle soit un entier à incrémentation automatique. Voici à quoi ressemble mon modèle

class Region(db.Model):
    __tablename__ = 'regions'
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    name = db.Column(db.String(100))
    parent_id = db.Column(db.Integer, db.ForeignKey('regions.id'))
    parent = db.relationship('Region', remote_side=id, primaryjoin=('Region.parent_id==Region.id'), backref='sub-regions')
    created_at = db.Column(db.DateTime, default=db.func.now())
    deleted_at = db.Column(db.DateTime)

Le code ci-dessus crée ma table mais ne fait pas id auto-incrémentation. Donc, si dans ma requête d'insertion, le champ id me manque, cela me donne cette erreur

ERREUR: la valeur nulle dans la colonne "id" viole la contrainte non nulle

J'ai donc changé la déclaration id pour qu'elle ressemble à ceci

id = db.Column(db.Integer, db.Sequence('seq_reg_id', start=1, increment=1),
               primary_key=True)

Toujours la même erreur. Quel est le problème avec le code ci-dessus?

33
lovesh

Il n'y a rien de mal avec le code ci-dessus. En fait, vous n'avez même pas besoin de autoincrement=True Ou db.Sequence('seq_reg_id', start=1, increment=1), car SQLAlchemy définira automatiquement la première colonne Integer PK qui n'est pas marquée comme FK comme autoincrement=True.

Ici, j'ai mis en place une configuration de travail basée sur la vôtre. L'ORM de SQLAlechemy se chargera de générer des id et de remplir les objets avec eux si vous utilisez la classe basée sur la base déclarative que vous avez défini pour créer des instances de votre objet.

from flask import Flask
from flask.ext.sqlalchemy import SQLAlchemy

app = Flask(__name__)
app.debug = True
app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://user:password@localhost/testdb'
app.config['SQLALCHEMY_ECHO'] = True
db = SQLAlchemy(app)

class Region(db.Model):
    __tablename__ = 'regions'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(100))

db.drop_all()
db.create_all()

region = Region(name='Over Yonder Thar')
app.logger.info(region.id) # currently None, before persistence

db.session.add(region)
db.session.commit()
app.logger.info(region.id) # gets assigned an id of 1 after being persisted

region2 = Region(name='Yet Another Up Yar')
db.session.add(region2)
db.session.commit()
app.logger.info(region2.id) # and 2

if __name__ == '__main__':
    app.run(port=9001)
31
nothankyou

Je pense que vous n'avez pas besoin de l'auto-incrémentation une fois que vous avez défini,

id = db.Column(db.Integer , primary_key=True , autoincrement=True)

Je pense que ça devrait être,

id = db.Column(db.Integer , primary_key=True)

il vous donnera l'unicité que vous recherchez.

0
MUGABA