SQLAlchemy:向MySQL数据库添加UUID列

xmd2e60i  于 2023-01-20  发布在  Mysql
关注(0)|答案(2)|浏览(462)

我需要向现有的SQLAlchemy / MySQL表中添加一个新的UUID列。
为此,我在数据库模型中添加了:

class MyTable(db.Model):
    uid = db.Column(db.BINARY(16), nullable=False, unique=True, default=uuid.uuid4)

这样做会生成以下alembic升级代码,当然,如果新列是null,则该代码不能作为默认值工作:

op.add_column('my_table', sa.Column('uid', sa.BINARY(length=16), nullable=True))
op.create_unique_constraint(None, 'my_table', ['uid'])

我尝试使用适当的server_default=...参数扩展db.Column(db.BINARY(16), nullable=False, unique=True, default=uuid.uuid4)定义,但无法找到为每一行生成新的随机UUID的参数。

如何添加新列并为所有现有行生成新的随机且唯一的UUID值?

使用sa.String代替sa.BINARY的解决方案也是可以接受的。

g9icjywg

g9icjywg1#

最后,我在alembic更新文件中手动创建了必要的UPDATE语句,以便为现有行分配唯一的UID。
对于新条目,SQLAlchemy列定义中的default=uuid.uuid4就足够了。
注意,MySQL UUID()函数为现有记录生成基于时间戳的UUID值,而通过Python/SQLAlchemy创建的新记录使用uuid.uuid4生成v4(随机)UUID,因此两者都是UUID,但您将看到哪些UUID是由UUID()生成的,因为它们只是在使用UPDATE语句生成时的第一个块中不同。

使用二进制列类型

class MyTable(db.Model):
    uid = db.Column(db.BINARY(16), nullable=False, unique=True, default=uuid.uuid4)
def upgrade():
    op.add_column('my_table', sa.Column('uid', sa.BINARY(length=16), nullable=False))
    op.execute("UPDATE my_table SET uid = (SELECT(UUID_TO_BIN(UUID())))")
    op.alter_column('my_table', 'uid', existing_type=sa.BINARY(length=16), nullable=False)
    op.create_unique_constraint(None, 'my_table', ['uid'])

使用字符串/varchar列类型

一个二个一个一个

alen0pnh

alen0pnh2#

根据server_default上的mysqlalchemy文档:
text()表达式将按原样呈现,不带引号:一个月一个月一个月
基于此,您的server_default定义应如下所示:

server_default=text('(UUID_TO_BIN(UUID())))')

然而,如果你的mysql版本早于v8.0.12,那么你就不能像这样使用服务器端的默认值,你需要使用python中设置uuid的默认值,或者你需要一个触发器,如下面的SO问题所示:MySQL set default id UUID

相关问题