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

Aar*_*ron 4 python mysql encryption sqlalchemy alembic

我有以下模型:

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))

Run Code Online (Sandbox Code Playgroud)

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 ###
Run Code Online (Sandbox Code Playgroud)

我添加了该行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
Run Code Online (Sandbox Code Playgroud)

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

for __init__forStringEncryptedType非常简单:

def __init__(self, type_in=None, key=None, engine=None, padding=None, **kwargs):
Run Code Online (Sandbox Code Playgroud)

显然EncryptedTypefor strings 已被弃用,取而代之的是StringEncryptedType,但很难进行切换。这里还需要发生什么?

sna*_*erb 5

传递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))
Run Code Online (Sandbox Code Playgroud)

生成这个 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)
Run Code Online (Sandbox Code Playgroud)