Tortoise ORM 实现PostgreSQL字段写入时PGP加密的问题求助
Tortoise ORM 实现PostgreSQL字段写入时PGP加密的问题求助
大家好,我目前在使用Tortoise ORM配合PostgreSQL做字段的PGP加解密操作,解密功能已经正常跑通,但在创建/更新记录时的加密操作遇到了卡壳,想请教下有没有解决思路。
已正常工作的解密实现
我通过继承Function类实现了解密逻辑,代码如下:
class _Decrypt(Function): def __init__(self, term: Any, key, alias: str | None = None) -> None: super().__init__("pgp_sym_decrypt", term, key, alias=alias) class Decrypt(Aggregate): database_func = _Decrypt
使用的时候通过annotate配合过滤,能正确生成SQL并执行:
await models.UserPhone.annotate(phone_decrypt=Decrypt("phone", key)).filter(phone_decrypt=phone)
对应的SQL日志是符合预期的:
DEBUG:tortoise.db_client:SELECT pgp_sym_decrypt("phone",$1) "phone_decrypt",1 FROM "users_phones" WHERE pgp_sym_decrypt("phone",$2)=$3 LIMIT $4: ['...', '...', '...', 1]
写入时加密的问题
但当我想在创建记录时加密字段值,仿照解密的写法实现Encrypt类时,却出了问题:
# 尝试的加密类,但无法正常工作 class Encrypt(Function): def __init__(self, term: Any, key, alias: str | None = None) -> None: super().__init__("pgp_sym_encrypt", term, key, alias=alias)
调用create方法时:
await models.UserPhone.create(phone=Encrypt(phone, key))
生成的SQL把Encrypt实例直接当成了字符串处理,完全没有解析成SQL函数:
DEBUG:tortoise.db_client:INSERT INTO "users_phones" ("id","phone") VALUES ($1,$2): ['id', "pgp_sym_encrypt('...','...')"]
随后Tortoise直接抛出操作异常:
tortoise.exceptions.OperationalError: invalid input for query argument $2: "pgp_sym_encrypt('...','... (a bytes-like object is required, not 'str')
我判断核心问题是:Tortoise在写入场景下,没有把Encrypt解析为SQL函数,而是直接把它当成普通字符串参数传入了。
我尝试过的无效方案
- 重写
get_sql()方法:完全没被调用到; - 重写
__str__方法:虽然会被调用,但只是返回函数的字符串形式,还是没解决SQL解析的问题; - 尝试
function_cast():这个方法只在查询字段时生效,写入场景下根本不触发。
求助点
想请教下,怎么才能让Tortoise在创建/更新记录时,把自定义的Encrypt类正确解析为SQL函数执行,而不是当成普通字符串参数处理?感谢各位的指点!




