Python 用uuid替换整数id字段

Python 用uuid替换整数id字段,python,postgresql,sqlalchemy,alembic,Python,Postgresql,Sqlalchemy,Alembic,我需要用uuid替换模型中的默认整数id。问题是它被用于另一个模型(foreignkey)。 您知道如何在不丢失数据的情况下执行此操作吗 class A(Base): __tablename__ = 'a' b_id = Column( GUID(), ForeignKey('b.id'), nullable=False, server_default=text("uuid_generate_v4()") ) class B(Base):

我需要用uuid替换模型中的默认整数id。问题是它被用于另一个模型(foreignkey)。 您知道如何在不丢失数据的情况下执行此操作吗

class A(Base):
    __tablename__ = 'a'

    b_id = Column(
       GUID(), ForeignKey('b.id'), nullable=False,
       server_default=text("uuid_generate_v4()")
    )

class B(Base):
    __tablename__ = 'b'
    id = Column(
        GUID(), primary_key=True,
        server_default=text("uuid_generate_v4()")
    )
不幸的是,它不起作用,我也担心我会打破这种关系

sqlalchemy.exc.ProgrammingError: (psycopg2.ProgrammingError) default for column "id" cannot be cast automatically to type uuid
我尝试过的Alembic迁移类似于:

op.execute('ALTER TABLE a ALTER COLUMN b_id SET DATA TYPE UUID USING (uuid_generate_v4())')

使用自动生成的UUID值将
id\u tmp
列添加到b,并将
b\u id\u tmp
列添加到a。更新外键上的a连接b,用相应的UUID填充
a.b\u id\u tmp
。然后删除
a.b_id
b.id
,重命名添加的列,并重新建立主键和外键

CREATE TABLE a(id int PRIMARY KEY, b_id int);
CREATE TABLE b(id int PRIMARY KEY);

ALTER TABLE a ADD CONSTRAINT a_b_id_fkey FOREIGN KEY(b_id) REFERENCES b(id);

INSERT INTO b VALUES (1), (2), (3);
INSERT INTO a VALUES (1, 1), (2, 2), (3, 2);

ALTER TABLE b ADD COLUMN id_tmp UUID NOT NULL DEFAULT uuid_generate_v1mc();
ALTER TABLE a ADD COLUMN b_id_tmp UUID;

UPDATE a SET b_id_tmp = b.id_tmp FROM b WHERE b.id = a.b_id;

ALTER TABLE a DROP COLUMN b_id;
ALTER TABLE a RENAME COLUMN b_id_tmp TO b_id;
ALTER TABLE b DROP COLUMN id;
ALTER TABLE b RENAME COLUMN id_tmp TO id;
ALTER TABLE b ADD PRIMARY KEY (id);
ALTER TABLE a ADD CONSTRAINT b_id_fkey FOREIGN KEY(b_id) REFERENCES b(id);

顺便说一句,索引v1 uuid比索引v4更有效,因为它们包含一些可复制的信息,如果您在一行中生成几个,您会注意到这些信息。除非出于外部安全原因需要更高的随机性,否则这是一个小节约。

使用自动生成的UUID值将
id\u tmp
列添加到b,并将
b\u id\u tmp
列添加到a。更新外键上的a连接b,用相应的UUID填充
a.b\u id\u tmp
。然后删除
a.b_id
b.id
,重命名添加的列,并重新建立主键和外键

CREATE TABLE a(id int PRIMARY KEY, b_id int);
CREATE TABLE b(id int PRIMARY KEY);

ALTER TABLE a ADD CONSTRAINT a_b_id_fkey FOREIGN KEY(b_id) REFERENCES b(id);

INSERT INTO b VALUES (1), (2), (3);
INSERT INTO a VALUES (1, 1), (2, 2), (3, 2);

ALTER TABLE b ADD COLUMN id_tmp UUID NOT NULL DEFAULT uuid_generate_v1mc();
ALTER TABLE a ADD COLUMN b_id_tmp UUID;

UPDATE a SET b_id_tmp = b.id_tmp FROM b WHERE b.id = a.b_id;

ALTER TABLE a DROP COLUMN b_id;
ALTER TABLE a RENAME COLUMN b_id_tmp TO b_id;
ALTER TABLE b DROP COLUMN id;
ALTER TABLE b RENAME COLUMN id_tmp TO id;
ALTER TABLE b ADD PRIMARY KEY (id);
ALTER TABLE a ADD CONSTRAINT b_id_fkey FOREIGN KEY(b_id) REFERENCES b(id);

顺便说一句,索引v1 uuid比索引v4更有效,因为它们包含一些可复制的信息,如果您在一行中生成几个,您会注意到这些信息。除非出于外部安全原因需要更高的随机性,否则这只是一个小节约。

我不确定这将如何保持现有关系。你能通过SQL语法或python/alembic代码来展示它吗?如果你看过的话,它相当于《迷失方舟的掠夺者》中的沙袋戏法,除了巨石较少。我添加了一个例子,我不确定这将如何保持现有的关系。你能通过SQL语法或python/alembic代码来展示它吗?如果你看过的话,它相当于《迷失方舟的掠夺者》中的沙袋戏法,除了巨石较少。我添加了一个示例。