无法创建自动递增的主键

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

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字段,它给我这个错误

ERROR: 列“ id”中的 null 值违反了非 null 约束

因此,我将 id声明更改为如下所示

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

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

156071 次浏览

以上代码没有任何错误。事实上,您甚至不需要 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)

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

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

我觉得应该是,

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

它会给你你所寻找的独特性。

所以我遇到了一个问题,我的 SQLite 表没有自动递增主键。我有一个稍微复杂的用例,我想在生产中使用 postgres,但是在测试中使用 sqlite,以便在持续部署时使生活变得更容易一些。

事实证明,SQLite 不喜欢定义为 BigIntegers 的列,为了增量到工作,它们应该设置为 Integers。值得注意的是,SQLAlchemy 可以按照以下方式使用 with _ variant 函数处理此场景。我想这个可能对某人有用:

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

详情请浏览这里 https://docs.sqlalchemy.org/en/13/dialects/sqlite.html

即使在添加了 autoincrement=True之后,我还是出现了同样的错误。

问题是我已经创建了迁移。所以我降级到之前的迁移,删除迁移,再次创建迁移并升级。

然后错误就消失了。

希望这能帮到别人。

折叠: 添加 autoincrement=True,并确保您的迁移得到更新和应用。

默认情况下,您的 id 自动递增,即使没有设置 auto = True 標志。

所以使用

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

您得到的错误是试图用 id 属性填充表的结果。插入查询在任何时候都不应该包含 id 属性,否则就会得到这个错误。

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

如果你想要一个自动递增的 id 字段为一个组合键(即。超过1个 db.Column(..)的定义与 primary_key=True,然后增加 autoincrement=True为我修复的问题。

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 将自动设置第一个 除非您定义了一个包含多个 primary_key=True的复合键,否则不将 FK 标记为 autoincrement=True < em > 的整数 PK 列

不能在列定义中添加“ auto 自動增量”標記,而且在 _ _ table _ _ name 之後添加“ _ _ table _ _ args”属性。 就像这样:

    __tablename__ = 'table-name'
__table_args__ = {'sqlite_autoincrement': True} -> This adds autoincrement to your primary key.

试试吧,我希望这对你有用;)!

在我的例子中,我只是添加了 id 作为外部参数,而不依赖于 sql

试试这个代码,对我很管用。

__init__函数中不指定 id,因此当您创建一个新的“ User”对象时,SQLAlchemy 将自动为您唯一地生成一个 id 号。

from flask import Flask
from flask_sqlalchemy import SQLAlchemy


app = Flask(__name__)


app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///users.sqlite3'
app.config['SQLAlCHEMY_TRACK_MODIFICATIONS'] = False


db = SQLAlchemy(app)


class User(db.Model):
_id = db.Column(db.Integer, primary_key = True, autoincrement = True)
username = db.Column(db.String(80), unique = True, nullable = False)
email = db.Column(db.String(120), unique = True, nullable = False)


def __init__(self, username, email):
self.username = username
self.email = email

这行代码将在数据库中创建预期的表。

with app.app_context():
db.create_all()




admin = User(username = 'another admin', email='another_admin@mail.com')
guest = User(username = 'another guest', email='another_guest@mail.com')

下面的代码将把我们的数据推送到表中。

with app.app_context():
db.session.add(admin)
db.session.add(guest)
db.session.commit()