主 ID 序列不递增
Primary id sequence not incrementing
我有一个 table 设置如下:
USERS_TABLE = \
Table("users", META_DATA,
Column("id", Integer, Sequence("user_id_seq"), primary_key=True),
Column("first_name", String(255)),
Column("last_name", String(255))
)
我可以像这样插入 单行:
INS_EXPRESSION = insert(USERS_TABLE)
SEQ = Sequence('user_id_seq')
INS_EXPRESSION.values(first_name="Foo", last_name="Bar")
但是,如果我尝试 第二次插入 ,我会收到此错误:
sqlalchemy.exc.IntegrityError: (psycopg2.IntegrityError) null value in column "id" violates not-null constraint
DETAIL: Failing row contains (null, null, null).
[SQL: 'INSERT INTO users DEFAULT VALUES']
如何使 user_id_seq
序列 自动递增 ?
问题是 Table
object definition gives us next CREATE TABLE
语句的当前版本
CREATE TABLE users (
id INTEGER NOT NULL,
first_name VARCHAR(255),
last_name VARCHAR(255),
PRIMARY KEY (id)
)
虽然它可能应该是
这个
CREATE TABLE users (
id INTEGER DEFAULT nextval('user_id_seq') NOT NULL,
first_name VARCHAR(255),
last_name VARCHAR(255),
PRIMARY KEY (id)
)
或者只是这个
CREATE TABLE users (
id SERIAL NOT NULL,
first_name VARCHAR(255),
last_name VARCHAR(255),
PRIMARY KEY (id)
)
所以每个语句的解决方案是:
在this recipe之后我们可以将server_default
设置为序列的nextval
like
from sqlalchemy import (MetaData, Table, Column,
Integer, String, Sequence,
create_engine,
insert)
db_uri = 'postgresql://username:password@hostname:5432/database'
engine = create_engine(db_uri)
META_DATA = MetaData(bind=engine)
user_id_seq = Sequence("user_id_seq", metadata=META_DATA)
USERS_TABLE = Table("users", META_DATA,
Column("id", Integer, user_id_seq,
server_default=user_id_seq.next_value(),
primary_key=True),
Column("first_name", String(255)),
Column("last_name", String(255)))
USERS_TABLE.create(checkfirst=True)
INS_EXPRESSION = insert(USERS_TABLE).values(first_name="Foo", last_name="Bar")
engine.execute(INS_EXPRESSION)
engine.execute('INSERT INTO users DEFAULT VALUES')
如果使用Sequence
is not crucial than we can remove it and just set autoincrement
flag to True
(it will also work with Sequence
removed without setting flag because
... SQLAlchemy will automatically set the first Integer PK column that's not marked as a FK as autoincrement=True
...
但它会更好,因为它更多 explicit):
from sqlalchemy import MetaData, Table, Column, Integer, String, create_engine, insert
db_uri = 'postgresql://username:password@hostname:5432/database'
engine = create_engine(db_uri)
META_DATA = MetaData(bind=engine)
USERS_TABLE = Table("users", META_DATA,
Column("id", Integer,
autoincrement=True,
primary_key=True),
Column("first_name", String(255)),
Column("last_name", String(255)))
USERS_TABLE.create(checkfirst=True)
INS_EXPRESSION = insert(USERS_TABLE).values(first_name="Foo", last_name="Bar")
engine.execute(INS_EXPRESSION)
engine.execute('INSERT INTO users DEFAULT VALUES')
我更喜欢第二个,因为使用 Sequence
看起来像 YAGNI。
P. S.
顺便问一下,你为什么要用 UPPER_CASE 的名字?这些对象看起来不像 constants to me since you can mutate them freely (PEP-8)
我有一个 table 设置如下:
USERS_TABLE = \
Table("users", META_DATA,
Column("id", Integer, Sequence("user_id_seq"), primary_key=True),
Column("first_name", String(255)),
Column("last_name", String(255))
)
我可以像这样插入 单行:
INS_EXPRESSION = insert(USERS_TABLE)
SEQ = Sequence('user_id_seq')
INS_EXPRESSION.values(first_name="Foo", last_name="Bar")
但是,如果我尝试 第二次插入 ,我会收到此错误:
sqlalchemy.exc.IntegrityError: (psycopg2.IntegrityError) null value in column "id" violates not-null constraint
DETAIL: Failing row contains (null, null, null).
[SQL: 'INSERT INTO users DEFAULT VALUES']
如何使 user_id_seq
序列 自动递增 ?
问题是 Table
object definition gives us next CREATE TABLE
语句的当前版本
CREATE TABLE users (
id INTEGER NOT NULL,
first_name VARCHAR(255),
last_name VARCHAR(255),
PRIMARY KEY (id)
)
虽然它可能应该是
这个
CREATE TABLE users ( id INTEGER DEFAULT nextval('user_id_seq') NOT NULL, first_name VARCHAR(255), last_name VARCHAR(255), PRIMARY KEY (id) )
或者只是这个
CREATE TABLE users ( id SERIAL NOT NULL, first_name VARCHAR(255), last_name VARCHAR(255), PRIMARY KEY (id) )
所以每个语句的解决方案是:
在this recipe之后我们可以将
server_default
设置为序列的nextval
likefrom sqlalchemy import (MetaData, Table, Column, Integer, String, Sequence, create_engine, insert) db_uri = 'postgresql://username:password@hostname:5432/database' engine = create_engine(db_uri) META_DATA = MetaData(bind=engine) user_id_seq = Sequence("user_id_seq", metadata=META_DATA) USERS_TABLE = Table("users", META_DATA, Column("id", Integer, user_id_seq, server_default=user_id_seq.next_value(), primary_key=True), Column("first_name", String(255)), Column("last_name", String(255))) USERS_TABLE.create(checkfirst=True) INS_EXPRESSION = insert(USERS_TABLE).values(first_name="Foo", last_name="Bar") engine.execute(INS_EXPRESSION) engine.execute('INSERT INTO users DEFAULT VALUES')
如果使用
Sequence
is not crucial than we can remove it and just setautoincrement
flag toTrue
(it will also work withSequence
removed without setting flag because... SQLAlchemy will automatically set the first Integer PK column that's not marked as a FK as
autoincrement=True
...但它会更好,因为它更多 explicit):
from sqlalchemy import MetaData, Table, Column, Integer, String, create_engine, insert db_uri = 'postgresql://username:password@hostname:5432/database' engine = create_engine(db_uri) META_DATA = MetaData(bind=engine) USERS_TABLE = Table("users", META_DATA, Column("id", Integer, autoincrement=True, primary_key=True), Column("first_name", String(255)), Column("last_name", String(255))) USERS_TABLE.create(checkfirst=True) INS_EXPRESSION = insert(USERS_TABLE).values(first_name="Foo", last_name="Bar") engine.execute(INS_EXPRESSION) engine.execute('INSERT INTO users DEFAULT VALUES')
我更喜欢第二个,因为使用 Sequence
看起来像 YAGNI。
P. S.
顺便问一下,你为什么要用 UPPER_CASE 的名字?这些对象看起来不像 constants to me since you can mutate them freely (PEP-8)