无法使用flask-sqlalchemy创建自动增量主键

时间:2013-12-30 22:02:45

标签: python postgresql sqlalchemy flask flask-sqlalchemy

我希望我的模型的主键是一个自动递增的整数。这是我的模型的样子

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)

上面的代码创建了我的表,但没有使id自动递增。因此,如果在我的插入查询中我错过了id字段,它会给我这个错误

  

错误:列“id”中的空值违反了非空约束

所以我将id声明更改为

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

仍然是同样的错误。上面的代码出了什么问题?

7 个答案:

答案 0 :(得分:32)

上述代码没有任何问题。实际上,您甚至不需要autoincrement=Truedb.Sequence('seq_reg_id', start=1, increment=1),,因为SQLAlchemy会自动将未标记为FK的第一个Integer PK列设置为autoincrement=True

在这里,我整理了一个基于你的工作设置。如果您使用已定义的基于声明基础的类来创建对象的实例,则SQLAlechemy的ORM将负责生成id并使用它们填充对象

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)

答案 1 :(得分:3)

我在模型类上声明复合键时遇到了这个问题。

如果您想要组合键的自动递增id字段(即,多个db.Column(..)primary_key=True定义,则添加autoincrement=True对我来说解决了这个问题。< / p>

class S3Object(db.Model):
    __tablename__ = 's3_object'

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

    # composite keys
    bucket_name = db.Column(db.String(), primary_key=True)
    key = db.Column(db.String(), primary_key=True)

因此,上述关于不需要autoincrement=True的陈述应为:

您甚至不需要autoincrement=True,因为SQLAlchemy会自动设置第一个 除非您要定义一个包含多个autoincrement=True

的组合键,否则不会将FK标记为primary_key=True 的整数PK列

答案 2 :(得分:2)

因此,我遇到了一个问题,即我的SQLite表没有自动增加主键。我有一个稍微复杂的用例,我想在生产中使用postgres,但用sqlite进行测试,以使连续部署时的工作变得轻松一些。

事实证明,SQLite不喜欢定义为BigIntegers的列,为了使其递增工作,应将它们设置为Integers。值得注意的是,SQLAlchemy可以使用with_variant函数来处理这种情况。认为这可能对某人有用:

.show()

更多详细信息,https://docs.sqlalchemy.org/en/13/dialects/sqlite.html

答案 3 :(得分:2)

即使添加了autoincrement=True,我也遇到了同样的错误。

问题是我已经创建了迁移。因此,我降级到先前的迁移,删除了迁移,再次创建了迁移并进行了升级。

然后错误消失了。

希望它可以帮助某人坚持下去。

总结:添加autoincrement=True,并确保更新和应用了迁移。

答案 4 :(得分:2)

即使没有设置autoincrement = True标志,您的ID默认也会自动增加。

所以使用没有问题

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

您遇到的错误是由于尝试使用id属性填充表而导致的。您的插入查询在任何时候都不应包含id属性,否则会出现该错误。

答案 5 :(得分:0)

我认为设置后就不需要自动递增

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

我认为应该是,

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

它将为您提供您所寻找的独特性。

答案 6 :(得分:-5)

我遇到了同样的问题,使用了flask-sqlalchemy和postgresql。我能够通过将id列更改为以下内容来解决它:

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