使用 StringEncryptedType、SQLAlchemy 时出现 VARCHAR 长度错误

VARCHAR length error when using StringEncryptedType, SQLAlchemy

我有以下型号:

from enum import Enum
from sqlalchemy_utils.types.encrypted.encrypted_type import StringEncryptedType
from sqlalchemy import (
    Column,
    Integer,
    Float,
    Enum as SQAEnum,
    String
)
from backend.db import Base
from backend.config import Config


class AuthProviders(Enum):
    google = "Google"
    facebook = "Facebook"
    vest = "Vest"


class Users(Base):
    __tablename__ = "users"

    id = Column(Integer, primary_key=True)
    email = Column(String(255), unique=True, index=True)
    hashed_password = Column(StringEncryptedType(String(255), Config.MYSQL_ENCRYPT_KEY))
    auth_provider = Column(SQAEnum(AuthProviders))
    timestamp = Column(Float(precision=32))

哪个 alembic 用于生成以下迁移脚本:

from alembic import op
import sqlalchemy as sa
from sqlalchemy_utils.types.encrypted.encrypted_type import StringEncryptedType

from backend.config import Config

# revision identifiers, used by Alembic.
revision = 'b919cf558155'
down_revision = None
branch_labels = None
depends_on = None


def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.create_table('users',
    sa.Column('id', sa.Integer(), nullable=False),
    sa.Column('email', sa.String(length=255), nullable=True),
    sa.Column('hashed_password', StringEncryptedType(sa.String(255), Config.MYSQL_ENCRYPT_KEY), nullable=True),
    sa.Column('auth_provider', sa.Enum('google', 'facebook', 'vest', name='authproviders'), nullable=True),
    sa.Column('timestamp', sa.Float(precision=32), nullable=True),
    sa.PrimaryKeyConstraint('id')
    )
    op.create_index(op.f('ix_users_email'), 'users', ['email'], unique=True)
    # ### end Alembic commands ###


def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.drop_index(op.f('ix_users_email'), table_name='users')
    op.drop_table('users')
    # ### end Alembic commands ###

我添加了 from sqlalchemy_utils.types.encrypted.encrypted_type import StringEncryptedType 行并编辑了 hashed_password 列条目,使其与模型文件匹配。

当我 运行 数据库升级时,我抛出了以下错误:

sqlalchemy.exc.CompileError: (in table 'users', column 'hashed_password'): VARCHAR requires a length on dialect mysql

我对此感到困惑,因为我已经定义了要加密的 String 的长度。将 String 替换为 VARCHAR 并不能解决问题。

StringEncryptedType__init__ 非常简单:

def __init__(self, type_in=None, key=None, engine=None, padding=None, **kwargs):

显然 EncryptedType 字符串已被弃用,取而代之的是 StringEncryptedType,但很难进行转换。这里还需要发生什么?

传递 String 列类型和单独的 length 关键字参数似乎可行。

这个模型

class Users(Base):
    __tablename__ = "users20201212a"

    id = Column(Integer, primary_key=True)
    email = Column(String(255), unique=True, index=True)
    hashed_password = Column(StringEncryptedType(String, length=255, key='abc'))
    auth_provider = Column(SQAEnum(AuthProviders))
    timestamp = Column(Float(precision=32))

生成此 DDL

CREATE TABLE users20201212a (
        id INTEGER NOT NULL AUTO_INCREMENT, 
        email VARCHAR(255), 
        hashed_password VARCHAR(255), 
        auth_provider ENUM('google','facebook','vest'), 
        timestamp FLOAT(32), 
        PRIMARY KEY (id)