incapable de créer la clé primaire d'auto-implémentation avec flask-sqlalchemy

je veux que la clé primaire de mon modèle soit un entier d'auto-identification. Voici comment mon modèle ressemble à

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 autoincrementing. Donc si dans ma requête insert je manque le id champ, il me donne cette erreur

ERREUR: valeur null dans la colonne "id" viole non-null constraint

alors j'ai changé le id déclaration à ressembler à ceci

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

Toujours le même erreur. Qu'est-ce qui ne va pas avec le code ci-dessus?

22
demandé sur Mel 2013-12-31 02:02:45

2 réponses

rien ne cloche avec le code ci-dessus. En fait, vous n'avez même pas besoin d' autoincrement=True ou db.Sequence('seq_reg_id', start=1, increment=1), comme SQLAlchemy définira automatiquement le premier Integer colonne 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 sqlalechémy s'occupera de générer des id et de peupler les objets avec eux si vous utilisez la classe de 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)
24
répondu nothankyou 2017-06-02 12:35:41

j'avais le même problème, en utilisant flask-sqlalchemy et postgresql. J'ai pu le résoudre en remplaçant la colonne id par la suivante:

id = db.Column(db.Integer, primary_key=True, default=lambda: uuid.uuid4().hex)

-4
répondu Goodword 2016-06-27 02:17:10