我尝试使用SQLAlchemy在PostgreSQL数据库中存储字节字符串。
我的模型看起来像这样:
class UserAccount(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String)
password_hash = db.Column(db.String)
password_salt = db.Column(db.String)
我希望password_hash
和password_salt
都是字节字符串(即str,因为我使用的是Python 2.7),但即使我将字节传递给它,SQLAlchemy似乎也将它们转换为进入unicode。我也尝试在模型中使用convert_unicode=False
,但我得到的结果相同。
我在SQLAlchemy模型中用什么来存储字节?
答案 0 :(得分:16)
使用LargeBinary
类型,它将在PostgreSQL上使用bytea
类型。如果您只使用PostgreSQL,也可以直接使用BYTEA
类型。
还有其他SQL标准类型,例如BINARY
,但它通常更容易使用LargeBinary
,因为SQLAlchemy将为每个数据库使用首选类型。
答案 1 :(得分:0)
对于较短的字节字符串,您还可以使用TypeDcorator来包装String
列类。然后使用您的自定义类型类HexByteString
作为Column
类型:
from sqlalchemy.types import Column, String, TypeDecorator
from sqlalchemy.ext.declarative import declarative_base
class HexByteString(TypeDecorator):
"""Convert Python bytestring to string with hexadecimal digits and back for storage."""
impl = String
def process_bind_param(self, value, dialect):
if not isinstance(value, bytes):
raise TypeError("HexByteString columns support only bytes values.")
return value.hex()
def process_result_value(self, value, dialect):
return bytes.fromhex(value) if value else None
Base = declarative_base()
class MyModel(Base):
data = Column(HexByteString)
然后,您可以将bytes
个实例分配给data
实例的MyModel
属性,它们将被转换为具有十六进制数字的字符串,并在传递给数据库或从数据库传递时返回。当然,这将使存储大小增加一倍,但是当直接查看数据库时,可以更轻松地查看列中存储的内容。
您可以将bytes.hex()
/ bytes.fromhex()
(需要Python 3.5+)替换为任何其他可以安全地将字节存储在Ascii字符串中的编码方案,例如Base64(base64.b64_encode(value).decode()
/ {{1 }}。