简体   繁体   English

如何让 Alembic 在 TEXT 列上发出长度约束?

[英]How do I get Alembic to emit a length constraint on a TEXT column?

I'm not sure if it's actually called "length constraint", but I have a SQL statement that works when testing in a local docker container with mysql:我不确定它是否真的被称为“长度约束”,但我有一个 SQL 语句,它在使用 mysql 在本地 docker 容器中进行测试时有效:

create unique index _uq_data on data(question_id, reply_id, text(50));

The constraint/length notation (50) is required since the TEXT field is variable length and may make the key too long.约束/长度符号(50)是必需的,因为 TEXT 字段是可变长度的,可能会使密钥太长。 When creating a Flask migration for this I tried:在为此创建 Flask 迁移时,我尝试过:

op.create_unique_constraint('_data_uc', 'data', ['question_id', 'reply_id', 'text(50)'])

But the SQL that Alembic generates for this quotes the whole last field:但是 Alembic 为此生成的 SQL 引用了整个最后一个字段:

ALTER TABLE data ADD CONSTRAINT _data_uc UNIQUE (question_id, reply_id, `text(50)`);

which gives the error这给出了错误

ERROR 1072 (42000): Key column 'text(50)' doesn't exist in table

How do I get this emitted as 'text'(50) rather than 'text(50)' ?如何将其作为'text'(50)而不是'text(50)'发出?

I recently faced the same issue, I considered 2 solutions/workarounds.我最近遇到了同样的问题,我考虑了 2 个解决方案/解决方法。

First solution第一个解决方案

Alter your columns to specify a length to them.更改您的列以指定它们的长度。 In your case, the columns seem to be IDs (as text), will they ever by longer than X characters ?在您的情况下,列似乎是 ID(作为文本),它们的长度会超过 X 个字符吗?

Second solution第二种解决方案

The create_index function allows various things in the columns list , including TextClause . create_index函数允许列列表中的各种内容,包括TextClause So you can create a non unique index with only a portion of the IDs, such as :因此,您可以创建仅包含一部分 ID 的非唯一索引,例如:

from sqlalchemy.sql.expression import text
from alembic import op

def upgrade():
    op.create_index(
        "_uq_data",
        "data",
        # 100 is arbitrary, but there is a limit to index key length
        # depending on your mysql version and database configuration
        [text("question_id(100)"), text("reply_id(100)")],
        unique=False
    )

Resulting in the following SQL statement :导致以下 SQL 语句:

CREATE INDEX _uq_data ON data (question_id(100), reply_id(100))

Alternative second solution替代的第二种解决方案

Still creating a "partial value index", but via sqlalchemy using mysql dialect param mysql_length :仍在创建“部分值索引”,但通过mysql_length使用mysql 方言参数mysql_length

Index(
    "_uq_data",
    "question_id",
    "reply_id",
    unique=False,
    mysql_length={"question_id": 100, "reply_id": 100},
    ),

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM