[英]Having two serial keys in postgresql via sqlalchemy
I have an unusual challenge. 我面临着不寻常的挑战。 I'm modifying a table to be able to join with two other legacy groups of PostgreSQL tables. 我正在修改一个表,使其能够与其他两个旧的PostgreSQL表组连接。
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) numeric_id = sql.Column(sql.Integer,primary_key = True)
The other group of tables all use UUID fields for the expected JOIN requests. 另一组表都将UUID字段用于预期的JOIN请求。 So the following field definition would work: 因此,以下字段定义将起作用:
uu_account_id = sql.Column(UUID(as_uuid=True), primary_key=True) 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.) (并且不行:更改其他表是不行的。过多的遗留代码。)
Make the uuid
column the primary key, like usual. 像往常一样,将uuid
列设为主键。
Define the other column as having serial
type and unique
. 将另一列定义为具有serial
类型和unique
。 In SQL I'd write 在SQL中,我会写
create table mytable (
mytable_id uuid primary key default uuid_generate_v4(),
mytable_legacy_id serial unique not null,
... other cols ...
);
so you just need to do the SQLAlchemy equivalent, whatever that is, of a not null
, unique
field. 因此,您只需要对一个not null
unique
字段执行等效的SQLAlchemy。
Note that "serial" is just shorthand for 请注意,“ 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;
so if you can't make sqlalchemy recognise that you can have a serial field that isn't a primary key, you can do it this way instead. 因此,如果您无法使sqlalchemy识别出您可以拥有不是主键的串行字段,则可以改用这种方式。
Between the SQLAlchemy, alembic (which I also use), and PostgreSQL, this turned out to be tricky. 在SQLAlchemy,alembic(我也使用过)和PostgreSQL之间,事实证明这很棘手。
If creating a brand new table from scratch, the following works for my numeric_id
column: 如果从头开始创建全新的表,则以下内容适用于我的numeric_id
列:
numeric_id = sql.Column(sql.Integer, sql.Sequence('mytable_numeric_id_seq'), unique=True, nullable=False)
(It is possible that the unique=True
and nullable=False
are overkill.) ( unique=True
和nullable=False
会过大。)
However, if modifying an existing table, the sequence itself fails to get created. 但是,如果修改现有表,则序列本身无法创建。 Or, at least, I couldn't get it to work. 或者,至少,我无法使其正常工作。
The sequence can be created by hand, of course. 当然,可以手动创建序列。 Or, if using 'alembic' to make distributed migrations easier, add: 或者,如果使用“ alembic”使分布式迁移更容易,请添加:
from sqlalchemy.schema import Sequence, CreateSequence
def upgrade():
op.execute(CreateSequence(Sequence("mytable_numeric_id_seq")))
To the version
script created by alembic. 到由alembic创建的version
脚本。
Special thanks to Craig for his help. 特别感谢Craig的帮助。
(Note: most of the SQLAlchemy examples on the net use db.
as the module alias rather than sql.
. Same thing really. I used sql.
simply because I'm using db.
already for MongoDB.) (注意:网上的大多数SQLAlchemy示例都使用db.
作为模块别名而不是sql.
确实是同一件事。我之所以使用sql.
仅仅是因为我已经为MongoDB使用db.
.。)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.