背景
我目前正在开发的应用程序正在从SQLite3过渡到PostgreSQL。使用当前数据库中的.dump
成功迁移了所有数据,更改了所有类型的表
CREATE TABLE foo (
id INTEGER NOT NULL,
bar INTEGER,
...
PRIMARY KEY (id),
FOREIGN KEY(bar) REFERENCES foobar (id),
...
);
到
CREATE TABLE foo (
id SERIAL NOT NULL,
bar INTEGER,
...
PRIMARY KEY (id),
FOREIGN KEY(bar) REFERENCES foobar (id) DEFERRABLE,
...
);
和SET CONSTRAINTS ALL DEFERRED;
。
因为我正在使用SQLAlchemy,所以我希望从那时开始顺利工作,当然要改变engine
。但问题似乎是主键自动增加到INSERT
上的唯一值。
该表格,foo
,我目前遇到问题,有7500多行,但序列foo_id_seq
的{{1}}设置在current value
上(因为我有尝试插入五次,现在所有插件都失败了。)
问题:
所以现在我的问题是,如果没有明确提供5
,在id
语句中,如果{{1,我如何让Postgres自动为INSERT
字段分配唯一值}}?或者更具体地说,让序列为它返回一个唯一值?
糖:
通过SQLAlchemy界面实现所有这些。
环境详情:
PS:如果有人为此问题找到更合适的标题,请进行编辑。
答案 0 :(得分:1)
您的PRIMARY KEY
应该被定义为使用SEQUENCE
作为DEFAULT
,通过SERIAL
便利伪类型:
CREATE TABLE blah (
id serial primary key,
...
);
或明确的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;
这是discussed in the SQLAlchemy documentation。
您可以将其添加到现有表格中:
CREATE SEQUENCE blah_id_seq OWNED BY blah.id;
ALTER TABLE blah ALTER COLUMN id SET DEFAULT nextval('blah_id_seq');
如果您希望恢复转储,请手动添加序列。
如果现有数据已直接加载到COPY
或类似的表中,则需要设置序列起点:
SELECT setval('blah_id_seq', max(id)+1) FROM blah;
我认为这个问题可能与您在SQLite中的开发有关,然后进行转储并将该转储恢复到PostgreSQL。 SQLAlchemy希望使用适当的默认值和序列创建自己的模式。
我建议你做的是让SQLAlchemy创建一个新的空数据库。将每个表的数据从SQLite DB转储到CSV,然后将COPY
该数据转储到PostgreSQL表中。最后,使用setval
更新序列,以便生成适当的值。
无论如何,需要以确保创建适当的序列。您可以通过SERIAL
伪列类型或手动SEQUENCE
创建和DEFAULT
设置来执行此操作,但您必须这样做。否则,无法以高效,并发安全的方式将生成的ID分配给表。
答案 1 :(得分:0)
使用
alter sequence foo_id_seq restart with 7600
下次调用序列时,应该给你7601。
http://www.postgresql.org/docs/current/static/sql-altersequence.html
然后是后续的价值观。只需确保使用值>重新启动它最后的身份。