Python 无法使用flask-sqlalchemy创建自动递增的主键

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20848300/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 21:22:52  来源:igfitidea点击:

unable to create autoincrementing primary key with flask-sqlalchemy

pythonpostgresqlsqlalchemyflaskflask-sqlalchemy

提问by lovesh

I want my model's primary key to be an autoincrementing integer. Here is how my model looks like

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

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)

The above code creates my table but does not make idautoincrementing. So if in my insert query I miss the idfield it gives me this error

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

ERROR: null value in column "id" violates not-null constraint

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

So I changed the iddeclaration to look like this

所以我把id声明改成这样

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

Still the same error. What is wrong with the code above?

还是一样的错误。上面的代码有什么问题?

回答by nothankyou

Nothing is wrong with the above code. In fact, you don't even need autoincrement=Trueor db.Sequence('seq_reg_id', start=1, increment=1),as SQLAlchemy will automatically set the first IntegerPK column that's not marked as a FK as autoincrement=True.

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

Here, I've put together a working setup based on yours. SQLAlechemy's ORM will take care of generating id's and populating objects with them if you use the Declarative Base based classthat you've defined to create instances of your object.

在这里,我已经根据您的设置组合了一个工作设置。如果您使用已定义的基于声明性基类的类来创建对象的实例,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)

回答by Goodword

I was having the same problem, using flask-sqlalchemy and postgresql. I was able to solve it by changing the id column to the following:

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

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

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

回答by MUGABA

I think you do not need the autoincrement once you set ,

我认为你一旦设置就不需要自动增量,

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

I think that it should be ,

我觉得应该是

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

it will give you the uniqueness your looking for .

它会给你你正在寻找的独特性。

回答by Iain Hunter

So I landed here with an issue that my SQLite table wasn't auto-incrementing the primary key. I have a slightly complex use case where I want to use postgres in production but sqlite for testing to make life a bit easier when continuously deploying.

所以我来到这里遇到一个问题,即我的 SQLite 表没有自动增加主键。我有一个稍微复杂的用例,我想在生产中使用 postgres,但使用 sqlite 进行测试,以便在持续部署时使生活更轻松。

It turns out SQLite doesn't like columns defined as BigIntegers, and for incrementing to work they should be set as Integers. Remarkably SQLAlchemy can handle this scenario as follows using the with_variant function. Thought this may be useful for someone:

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

id = db.Column(db.BigInteger().with_variant(db.Integer, "sqlite"), primary_key=True)

Further details here https://docs.sqlalchemy.org/en/13/dialects/sqlite.html

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