sqlalchemy column_property 或类似的 table 对象

sqlalchemy column_property or similar for table object

我对 FastAPI 和 SqlAlchemy 还很陌生。 我有一个 table 这样的

import sqlalchemy
from sqlalchemy import Integer, Column, String

Agents = sqlalchemy.Table(
'agents',
metadata,
sqlalchemy.Column('id', Integer, primary_key=True),
sqlalchemy.Column('name', String(500))
)

现在,当值保存到 name 列时,我们使用 PostgreSQLPgcrypto 模块保存名称的加密版本。如果这是基于 sqlalchemy.orm 的 table,那么我可以在保存和 selecting 时使用 column_property 即时加密和解密。这种基于 table 的对象是否有类似的东西?否则,现在,我必须像这样

手动解密每个 select 的值
from sqlalchemy import select,func, LargeBinary,cast

select([Agents, func.pgp_sym_decrypt(cast(Agents.c.name, LargeBinary), '**SECRET_KEY**').label('name')])

你看我每次都要解密。有什么方法可以让我在使用 Agents table 时即时解密?

提前感谢您的帮助。

您可以创建自定义类型:

from sqlalchemy import String, func, type_coerce, TypeDecorator
from sqlalchemy.dialects.postgresql import BYTEA


class PGPString(TypeDecorator):
    impl = BYTEA
    cache_ok = True

    def __init__(self, passphrase):
        super(PGPString, self).__init__()
        self.passphrase = passphrase

    def bind_expression(self, bindvalue):
        return func.pgp_sym_encrypt(
            type_coerce(bindvalue, String),
            self.passphrase
        )

    def column_expression(self, col):
        return func.pgp_sym_decrypt(col, self.passphrase)


Agents = sqlalchemy.Table(
    'agents',
    metadata,
    sqlalchemy.Column('id', Integer, primary_key=True),
    sqlalchemy.Column('name', PGPString("**SECRET_KEY**"))
)

查看更多示例here