Обратите внимание, что я обнаружил проблемы, похожие на мою, но ни одно из исправлений не применимо. Также обратите внимание, что этот код работает в Python 2.7, но не в 3.7.
Проблема в том, что у меня есть следующая модель:
class Client(Base, UserMixin):
"""
Represents a client in the database.
:param id: primary key of test in database
:param uuid: String representation of UUID Version 4 (Random). If client
does not specify, it will generate one on the server. This can be used to
check if things have been uploaded.
:param username: the username for the client, must be unique system-wide.
:param password: the bcrypt password hash for the client.
"""
__tablename__ = 'clients'
__form_keys__ = {'username', 'password', 'is_system_administrator'}
__keys__ = __form_keys__ | {'id', 'uuid', 'client_id'}
__hidden_keys__ = {'username', 'password'}
username = Column(String(255), unique=True, nullable=False)
password = Column(BINARY(60), nullable=False)
где, согласно требованиям bcrypt
, пароль кодируется с использованием типа данных BINARY, а затем хешируется.
Когда я пытаюсь вставить в таблицу, я получаю сообщение об ошибке:
sqlalchemy.exc.StatementError: (builtins.TypeError) string argument without an encoding
[SQL: INSERT INTO clients (uuid, username, password, is_system_administrator) VALUES (%(uuid)s, %(username)s, %(password)s, %(is_system_administrator)s)]
[parameters: [{'is_system_administrator': True, 'password': '$2a$12$ED6YdEPAb5pt0wTMno9M/OhpCNXo1CyPxmZuUK.YHdxrahW67DEDS', 'username': 'username'}]]
Чем моя проблема отличается от ответов, которые я нашел, так это тем, что, например, здесь sqlalchemy-insert-string-argument-without-encoding, выполняемый запрос собирается непосредственно с использованием столбцов модели, поэтому легко сделать кодирование на данном этапе.
Я безуспешно пытался выяснить, где это закодировать, и даже пытался переключить тип данных с BINARY на TEXT (бэкэнд — MySQL), но ничего не помогло.
Я не совсем уверен, как поступить.
Я смог воспроизвести вашу проблему, используя
session.add(
Client(
is_system_administrator=True,
password = "$2a$12$ED6YdEPAb5pt0wTMno9M/OhpCNXo1CyPxmZuUK.YHdxrahW67DEDS",
username = "username",
)
)
Тем не менее, это, кажется, работает
session.add(
Client(
is_system_administrator=True,
password=bytes(
"$2a$12$ED6YdEPAb5pt0wTMno9M/OhpCNXo1CyPxmZuUK.YHdxrahW67DEDS",
"ascii",
),
username = "username",
)
)