【发布时间】:2017-08-12 06:28:38
【问题描述】:
简而言之我的问题:是否可以在 SQLAlchemy 中访问自定义类型的原始值?
我对自定义类型的实现:
class JSONDocument(TypeDecorator):
# override field
impl = JSON
# Write
def process_bind_param(self, value, dialect):
if value is not None:
req = requests.post(url, data=json.dumps({'data': value}))
uri = req.json()['uri']
value = uri
return value
# Read
def process_result_value(self, value, dialect):
if value is not None:
uri = value
req = requests.get(uri)
value = req.json()['data']
return value
我的桌子模型:
class SomeTable(db.Model):
id = db.Column(db.Integer, primary_key=True)
# The column with large json data
json_data = db.Column(JSONDocument)
每当我尝试更新或插入一行,结果将写入json_data 列时,SQLAlchemy 将调用JSONDocument 的process_bind_param。然后它会执行一个 POST API 调用,在我的 NoSQL 表中创建一个新的数据条目,并将我的 SQL 表中的 json_data 列更新为返回的 URI。
每当我尝试访问 json_data 列时,它都会对存储在我的 SQL 表中的 URI 执行 GET API 调用,并返回存储在我的 NoSQL 表中的实际 JSON 数据。
我的问题:如何获取存储在JSONDocument 覆盖的SQL 表中的URI?每当我更新 json_data 时,我都想对旧 URI 执行 DELETE API 调用。
我已经尝试使用 SQLAlchemy 的 Mapping 事件回调,但我仍然无法获取自定义类型背后的 URI。
如果我的问题问得不够清楚,请告诉我。任何建议或想法表示赞赏。
我正在尝试做的任务的总结:
我有一个包含以下列的 Postgresql 数据库 (RDS) 表:id(int)、json_data(string)、other_columns...
由于json_data 列占用了太多存储空间,我正在努力将该列中的数据移动到其他 NoSQL 数据库 (DynamoDB)。我实现了一个 RESTful API 服务器,用于在我的 NoSQL 表中更新、插入和软删除数据。
我想实现一个 SQLAlchemy 自定义类型,当我的应用尝试访问其他 Python 代码中的 json_data 列时,它会自动调用我的 API 方法。
【问题讨论】:
-
你的意思是在读取过程中沿着值返回uri吗?
-
不完全,我只想要常规读取期间的值。通过常规阅读,我的意思是
result = SomeTable.query.first().json_data。我在问是否有result.raw_value之类的东西,以便我可以获取自定义类型后面的URI。 -
有多种方法可以解决这个问题,但没有“内置”解决方案,因为流程绑定和流程结果都是由您编写的。第一 - 你可以使用“self.uri = value”代替“uri = value”,而不是“req = requests.get(uri)”使用“req = requests.get(self.uri)”。这样 uri 应该可以通过“result.uri”访问。第二种选择是通过 session.execute() 使用纯 SQL。或者你甚至可以创建另一个继承自 JSONDocument 的类,然后再次覆盖 process_result_value :)
-
@PeterMajko 非常感谢您的建议!我实际上确实尝试了第一种方法,但似乎每个自定义类型实例共享相同的
JSONDocument实例,因为当我更新一行json_data的“self.uri”时,其他行的“self.uri” 'json_data也将更新为相同的内容。你能详细说明你提到的最后一种方法吗?或者是否有任何文件或文章我可以查看它是如何工作的?谢谢! -
当我写我之前的评论时,我无法尝试。现在我到了电脑,不幸的是我的“想法”是错误的。对不起。因为当您访问 SameTable.json_data 时,它已经提供了数据类型实例而不是 TypeDecorator 一个。你可以使用类似“返回值,uri”的东西,然后当你访问 some_table_instance.json_data[0] 你得到你的 JSON 和 some_table_instance.json_data[1] 你得到 uri。这样合适吗?
标签: python sqlalchemy