[英]Set SQLAlchemy to use PostgreSQL SERIAL for identity generation
Background: 背景:
The application I am currently developing is in transition from SQLite3 to PostgreSQL. 我目前正在开发的应用程序正在从SQLite3过渡到PostgreSQL。 All the data has been successfully migrated, using the
.dump
from the current database, changing all the tables of the type 使用当前数据库中的
.dump
成功迁移了所有数据,更改了该类型的所有表
CREATE TABLE foo (
id INTEGER NOT NULL,
bar INTEGER,
...
PRIMARY KEY (id),
FOREIGN KEY(bar) REFERENCES foobar (id),
...
);
to 至
CREATE TABLE foo (
id SERIAL NOT NULL,
bar INTEGER,
...
PRIMARY KEY (id),
FOREIGN KEY(bar) REFERENCES foobar (id) DEFERRABLE,
...
);
and SET CONSTRAINTS ALL DEFERRED;
和
SET CONSTRAINTS ALL DEFERRED;
. 。
Since I am using SQLAlchemy I was expecting things to work smoothly from then on, after of course changing the engine
. 因为我正在使用SQLAlchemy,所以我希望从那时开始顺利工作,当然是在改变
engine
。 But the problem seems to be with the autoincrement of the primary key to a unique value on INSERT
. 但问题似乎是将主键自动增加到
INSERT
上的唯一值。
The table, say foo
, I am currently having trouble with has 7500+ rows but the sequence foo_id_seq
's current value
is set on 5
(because I have tried the inserts five times now all of which have failed). 表
foo
,我目前遇到问题的表有7500+行,但序列foo_id_seq
的current value
设置为5
(因为我已经尝试了五次插入,现在所有这些都失败了)。
Question: 题:
So now my question is that without explicitly supplying the id
, in the INSERT
statement, how can I make Postgres automatically assign a unique value to the id
field if foo
? 所以现在我的问题是,如果没有显式提供
id
,在INSERT
语句中,如果foo
,我如何让Postgres自动为id
字段分配一个唯一值? Or more specifically, have the sequence return a unique value for it? 或者更具体地说,让序列为它返回一个唯一值?
Sugar: 糖:
Achieve all that through the SQLAlchemy interface. 通过SQLAlchemy界面实现所有这一切。
Environment details: 环境细节:
PS: If anybody finds a more appropriate title for this question please edit it. PS:如果有人为这个问题找到更合适的标题,请编辑它。
Your PRIMARY KEY
should be defined to use a SEQUENCE
as a DEFAULT
, either via the SERIAL
convenience pseudo-type: 您的
PRIMARY KEY
应该定义为使用SEQUENCE
作为DEFAULT
,或者通过SERIAL
方便的伪类型:
CREATE TABLE blah (
id serial primary key,
...
);
or an explicit SEQUENCE
: 或明确的
SEQUENCE
:
CREATE SEQUENCE blah_id_seq;
CREATE TABLE blah (
id integer primary key default nextval('blah_id_seq'),
...
);
ALTER SEQUENCE blah_id_seq OWNED BY blah.id;
This is discussed in the SQLAlchemy documentation . 这在SQLAlchemy文档中讨论 。
You can add this to an existing table: 您可以将其添加到现有表中:
CREATE SEQUENCE blah_id_seq OWNED BY blah.id;
ALTER TABLE blah ALTER COLUMN id SET DEFAULT nextval('blah_id_seq');
if you prefer to restore a dump then add sequences manually. 如果您希望还原转储,请手动添加序列。
If there's existing data you've loaded directly into the tables with COPY
or similar, you need to set the sequence starting point: 如果现有数据已直接加载到具有
COPY
或类似的表中,则需要设置序列起点:
SELECT setval('blah_id_seq', max(id)+1) FROM blah;
I'd say the issue is likely to be to do with your developing in SQLite, then doing a dump and restoring that dump to PostgreSQL. 我说这个问题可能与您在SQLite中的开发有关,然后进行转储并将该转储恢复到PostgreSQL。 SQLAlchemy expects to create the schema its self with the appropriate defaults and sequences.
SQLAlchemy希望使用适当的默认值和序列创建自己的模式。
What I recommend you do instead is to get SQLAlchemy to create a new, empty database. 我建议你做的是让SQLAlchemy创建一个新的空数据库。 Dump the data for each table from the SQLite DB to CSV, then
COPY
that data into the PostgreSQL tables. 将每个表的数据从SQLite DB转储到CSV,然后将该数据
COPY
到PostgreSQL表中。 Finally, update the sequences with setval
so they generate the appropriate values. 最后,使用
setval
更新序列,以便生成适当的值。
One way or the other, you will need to make sure that the appropriate sequences are created. 无论如何,您需要确保创建适当的序列。 You can do it by
SERIAL
pseudo-column types, or by manual SEQUENCE
creation and DEFAULT
setting, but you must do it. 您可以通过
SERIAL
伪列类型或手动SEQUENCE
创建和DEFAULT
设置来完成,但您必须这样做。 Otherwise there's no way to assign a generated ID to the table in an efficient, concurrency-safe way. 否则,无法以高效,并发安全的方式将生成的ID分配给表。
Use 采用
alter sequence foo_id_seq restart with 7600
should give you 7601 next time you call the sequence. 下次拨打电话时应该给你7601。
http://www.postgresql.org/docs/current/static/sql-altersequence.html http://www.postgresql.org/docs/current/static/sql-altersequence.html
And then subsequent values. 然后是后续的价值观。 Just make sure that you restart it with a value > the last id.
只需确保使用值>最后一个ID重新启动它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.