Having two serial keys in postgresql via sqlalchemy

时间:2015-10-30 23:05:42

标签: python postgresql sqlalchemy

I have an unusual challenge. I'm modifying a table to be able to join with two other legacy groups of PostgreSQL tables.

One group pretty much requires that each record in the table have a unique integer. So, the following field definition would work:

numeric_id = sql.Column(sql.Integer, primary_key=True)

The other group of tables all use UUID fields for the expected JOIN requests. So the following field definition would work:

uu_account_id = sql.Column(UUID(as_uuid=True), primary_key=True)

But, clearly, I can't have two primary keys. So one of them needs to not be a primary key. It would be nice to simply have both still be automatically assigned when a new record is made.

Any suggestions?

I'm sure I can do a quick hack, but I'm curious if there is a nice clean answer.

(And no: changing the other tables is NOT an option. Way too much legacy code.)

2 个答案:

答案 0 :(得分:1)

uuid列设为主键,与往常一样。

将其他列定义为serial类型和unique。在SQL中我写

create table mytable (
    mytable_id uuid primary key default uuid_generate_v4(),
    mytable_legacy_id serial unique not null,
    ... other cols ...
);

所以你只需要对not nullunique字段进行SQLAlchemy等效操作。

请注意" serial"

只是简写
create sequence tablename_colname_seq;
create table tablename (
    colname integer default nextval('tablename_colname_seq'),
    ... cols ...
);
alter sequence tablename_colname_seq owned by tablename.colname;

因此,如果您无法让sqlalchemy认识到您可以拥有一个不是主键的序列字段,那么您可以这样做。

答案 1 :(得分:0)

在SQLAlchemy,alembic(我也使用)和PostgreSQL之间,结果证明这很棘手。

如果从头开始创建一个全新的表格,以下内容适用于我的numeric_id列:

numeric_id = sql.Column(sql.Integer, sql.Sequence('mytable_numeric_id_seq'), unique=True, nullable=False)

unique=Truenullable=False可能过度杀伤。)

但是,如果修改现有表,则序列本身无法创建。或者,至少,我无法让它发挥作用。

当然,可以手工创建序列。或者,如果使用' alembic'要使分布式迁移更容易,请添加:

from sqlalchemy.schema import Sequence, CreateSequence

def upgrade():
    op.execute(CreateSequence(Sequence("mytable_numeric_id_seq")))

由alembic创建的version脚本。

特别感谢克雷格的帮助。

(注意:网上的大多数SQLAlchemy示例使用db.作为模块别名而不是sql.。真的一样。我使用sql.只是因为我' m已经为MongoDB使用db.。)