简体   繁体   English

将SQLAlchemy设置为使用PostgreSQL SERIAL进行标识生成

[英]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_seqcurrent 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: 环境细节:

  • Python 2.6 Python 2.6
  • SQLAlchemy 8.2 SQLAlchemy 8.2
  • PostgreSQL 9.2 PostgreSQL 9.2
  • psycopg2 - 2.5.1 (dt dec pq3 ext) psycopg2 - 2.5.1(dt dec pq3 ext)

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.

相关问题 通过SQLAlchemy在PostgreSQL中有两个串行键 - Having two serial keys in postgresql via sqlalchemy 金字塔框架中Postgresql串行主键的sqlalchemy参数 - sqlalchemy argument for postgresql serial primary key in pyramid framework 如何在 SQLAlchemy(特别是 Flask-SQLAlchemy)中使用 PostgreSQL 扩展? - How to use PostgreSQL extensions in SQLAlchemy (specifically Flask-SQLAlchemy)? SQLAlchemy可以使用PostgreSQL的“from only”子句吗? - Can SQLAlchemy use the “from only” clause of PostgreSQL? SqlAlchemy 在查询中使用 PostgreSQL timestamptz “AT TIMEZONE” - SqlAlchemy use PostgreSQL timestamptz “AT TIMEZONE” in queries 使用 Z26C231D9E6ACBC7FF10118D262F3F5EZ 使 Sqlalchemy 在过滤器中使用日期 - Make Sqlalchemy Use Date In Filter Using Postgresql 序列金钥产生与验证 - Serial Key Generation and Validation 如何在 SQLAlchemy for PostgreSQL 中设置事务隔离级别? - How do I set the transaction isolation level in SQLAlchemy for PostgreSQL? 如何在 sqlAlchemy (postgreSQL) 中为 JSONB 列设置更复杂的默认值 - How to set a more complex default value for a JSONB column in sqlAlchemy (postgreSQL) 如何在 PostgreSQL 与 SQLAlchemy 和 psycopg2 的连接上设置“lock_timeout”? - How to set `lock_timeout` on a PostgreSQL connection with SQLAlchemy and psycopg2?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM