Description
When querying a record with a column of EncryptedType in python3.7 with a MySQL backend and packages
- SQLAlchemy==1.3.1
- SQLAlchemy-Utils==0.33.11
- mysql-connector-python==8.0.15
The query fails with TypeError: 'string argument without an encoding'.
The issue appears to be that EncryptedType has an impl
of LargeBinary which in python3 processes the returned value with the command
value = bytes(value)
However the value is an Unicode string and therefore the above call is not valid. The following code reproduces the error
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Unicode, create_engine, Integer
from sqlalchemy_utils import EncryptedType
from sqlalchemy.orm import sessionmaker
from sqlalchemy_utils.types.encrypted.encrypted_type import AesGcmEngine
Base = declarative_base()
class MyTable(Base):
__tablename__ = 'test'
id = Column('table_id', Integer, primary_key=True)
field = Column('field', EncryptedType(Unicode(250), 'secret', AesGcmEngine, 'pkcs5'))
engine = create_engine('mysql+mysqlconnector://user:password@localhost/scratch?charset=utf8')
Base.metadata.create_all(engine)
Session = sessionmaker(bind=engine)
session = Session()
session.add(MyTable(field='to encrypt'))
session.commit()
session.query(MyTable).all()
Traceback (most recent call last):
File "/tmp/tester.py", line 28, in
session.query(MyTable).all()
File "/tmp/python/lib/python3.7/site-packages/sqlalchemy/orm/query.py", line 3161, in all
return list(self)
File "/tmp/python/lib/python3.7/site-packages/sqlalchemy/orm/loading.py", line 105, in instances
util.raise_from_cause(err)
File "/tmp/python/lib/python3.7/site-packages/sqlalchemy/util/compat.py", line 383, in raise_from_cause
reraise(type(exception), exception, tb=exc_tb, cause=cause)
File "/tmp/python/lib/python3.7/site-packages/sqlalchemy/util/compat.py", line 129, in reraise
raise value
File "/tmp/python/lib/python3.7/site-packages/sqlalchemy/orm/loading.py", line 85, in instances
rows = [proc(row) for row in fetch]
File "/tmp/python/lib/python3.7/site-packages/sqlalchemy/orm/loading.py", line 85, in
rows = [proc(row) for row in fetch]
File "/tmp/python/lib/python3.7/site-packages/sqlalchemy/orm/loading.py", line 572, in _instance
populators,
File "/tmp/python/lib/python3.7/site-packages/sqlalchemy/orm/loading.py", line 693, in populate_full
dict[key] = getter(row)
File "/tmp/python/lib/python3.7/site-packages/sqlalchemy/sql/type_api.py", line 1247, in process
return process_value(impl_processor(value), dialect)
File "/tmp/python/lib/python3.7/site-packages/sqlalchemy/sql/sqltypes.py", line 943, in process
value = bytes(value)
TypeError: string argument without an encoding