I have the following model:
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))
which alembic uses to generate the following migration script:
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 ###
I added the line from sqlalchemy_utils.types.encrypted.encrypted_type import StringEncryptedType
and edited the hashed_password
column entry so that it matches the models file.
When I run the DB upgrade I'm thrown the following error:
sqlalchemy.exc.CompileError: (in table 'users', column 'hashed_password'): VARCHAR requires a length on dialect mysql
I'm confused by this, because I've defined the length of the String
that's being encrypted. Replacing String
with VARCHAR
doesn't solve the problem.
The __init__
for for StringEncryptedType
is pretty straight-forward:
def __init__(self, type_in=None, key=None, engine=None, padding=None, **kwargs):
Apparently EncryptedType
for strings is deprecated in favor of StringEncryptedType
, but having a hard time making the switch. What else needs to happen here?
Passing the String
column type and a separate length
keyword argument seems to work.
This model
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))
generates this 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)