使用 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)
我有以下型号:
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)