【发布时间】:2018-07-13 06:22:53
【问题描述】:
DRF 的基本用例似乎是“资源”(在 API 端)到表(在数据库端)的一对一映射。
具体来说,假设我们有一个包含一个或多个“项目”的“区域设置”实体:“区域设置”表示一组项目中的通用地理和管理信息——如果它针对一个项目进行更改,我们需要针对一个项目进行更改全部。
我们在数据库中将其以规范化形式表示为Locale 和Projects 表,而不是结合两者的非规范化Locale + Projects 表,在Projects 表中使用“Locale ID”作为外键。但是,我们希望对 api 用户隐藏这种规范化——我们只想公开一个 /project/ 端点,该端点返回与关联的 Locale 数据连接的 Project 数据,就好像它来自非规范化表一样。
当 DRF 中的单个 API 资源由后端数据库上的多个模型(以及表)组成时,如何表示它?
技术说明:
- 我在 posgtresql 9.6 中的后端
- 这不是一个事务性数据库,因此我们预计每天更新 10-15 次,而不是每秒 100 次。
到目前为止我的想法
(1) 在后端创建一个物化视图来执行连接,然后在 Django 中创建一个单独存在的非托管模型以支持 GET 请求。
优点:似乎最适合与 Django/DRF 用例相结合,因为我只是 创建另一个表和模型(尽管具有只读功能)。
缺点:如果我想确保用户看到他们对基础数据的更改(例如,更改语言环境中的一些信息),我需要在每次更新后刷新物化视图。我可能会同时使用 REFRESH MATERIALIZED VIEW 来至少允许视图在更新时起作用。
所以,+1 表示易于实施,-1 表示货币。
(2) 在后端使用原始参数化 SQL 查询来设置 JOIN 并返回结果。
优点:避免更新后刷新物化视图的问题。
缺点:适应复杂的查询似乎很棘手——我认为这可能会变得脆弱。
(3) 非规范化,所以我们有一个LocaleProjects 表
优点:简单。
缺点:数据一致性受到影响。如果语言环境记录发生更改,则需要编写额外的后端查询来更新共享语言环境的记录。
任何额外的输入都会有所帮助。
【问题讨论】:
-
“DRF 的基本用例似乎是“资源”(在 API 端)到表(在数据库端)的一对一映射。事实并非如此。你为什么这么认为?
-
@philipxy 序列化程序是围绕模型构建的,模型是围绕表构建的。我没有看到太多展示如何创建一个实际表示两个表连接的模型。这就是为什么。如果我错了,我会很高兴,有人可以告诉我 DRF 如何处理资源表示为基础数据库中多个表的连接的情况。
标签: rest django-models django-rest-framework relational-database