我在postgres数据库中有两个外来表,它们是“相关的”,没有通过“外键”正式连接(出于安全原因),称为帐户和配置文件。
帐户有一个名为'encrypted_UUID'的列,而Profile有一个名为'UUID'的列,其中Account中的一行可以与Profile中的一行非正式关联,方法是解密帐户的UUID并使用解密的方式搜索Profile中的行UUID。
我已成功使用M2Crypto从帐户解密个别UUID:
import hashlib
import M2Crypto.EVP
ENCRYPT = 1
DECRYPT = 0
def hash_key(key_phrase=None):
hasher512 = hashlib.sha512()
if key_phrase is None: # get from vault
key_phrase = vault_key
hasher512.update(str(key_phrase))
return hasher512.digest()
def crypt(data, key_phrase=None, iv=None, whichway=DECRYPT):
key = hash_key(key_phrase)
if iv is None:
iv = vault_iv
cipher = M2Crypto.EVP.Cipher(algo, key, iv, whichway)
return cipher.update(data) + cipher.final()
def decrypt(data, key_phrase=None, iv=None):
return crypt(data, key_phrase, iv, DECRYPT)
def encrypt(data, key_phrase=None, iv=None):
#data = data.encode('utf-8')
return crypt(data, key_phrase, iv, ENCRYPT)
其中vault_key
,vault_iv
和algo
是我将保密但用于加密/解密的内容。
因此,对于任何帐户,我可以说decrypt(Account.query.all()[0].uuid)
并获取解密的UUID字符串,然后查找具有该解密的UUID的相应配置文件。
现在,我正在尝试使用SQLAlchemy为两个表帐户和配置文件进行连接,使用两个帐户为帐户上的解密UUID使用计算列。
以下是我对模特的看法:
class Account(db.Model):
encrypted_uuid = db.Column(db.LargeBinary())
...
@hybrid_property
def decrypted_uuid(self):
return decrypt(self.encrypted_uuid)
@decrypted_uuid.expression
def decrypted_uuid(cls):
return decrypt(cls.encrypted_uuid)
class Profile(db.Model):
uuid = db.Column(db.String())
...
这是我对加入的尝试:
query = db.session
.query(Account.email, Profile.last_name, Profile.first_name)
.join(Profile, Profile.uuid == Account.decrypted_uuid)
但是,当我尝试进行查询时出现错误:
TypeError: expected a readable buffer object
可以将堆栈追溯到decrypt
模型中cls.encrypted_uuid
上的Account
调用。
根据我过去的经验,通过几乎完全模仿hybrid_property / method定义下的计算来获得计算列。
我有一种感觉这是因为我试图在类decrypt
而不是像sqlalchemy.orm.attributes.InstrumentedAttribute object
函数期望的str
类上调用decrypt