在删除表格时在 Objection.js 中保留关系图

Posted

技术标签:

【中文标题】在删除表格时在 Objection.js 中保留关系图【英文标题】:Keep a relation map in Objection.js while removing the table 【发布时间】:2020-07-19 06:47:14 【问题描述】:

我正在开发一个类似 reddit 的网站,其中投票存储每个用户(而不是每个帖子)。这是我的相关架构:

内容

id | author_id | title       | text
---|-----------|-------------|---
1  | 1 (adam)  | First Post  | This is a test post by adam

投票:任何人在任何帖子上投票的所有投票

id | voter_id    | content_id       | category_id
---|-------------|------------------|------------
1  | 1 (adam)    | 1 ("First Post") | 1 (upvote)
2  | 2 (bob)     | 1 ("First Post") | 1 (upvote)

vote_count:当前所有用户在帖子中收到的总票数(“计数”)

id | content_id       | category_id  | count
---|------------------|--------------|-------
1  | 1 ("First Post") | 1 (upvote)   | 2

我在Objection.js 模型中为content 表定义了voteCount relation:

class Content extends Model   
  static tableName = 'content';
  static relationMappings = 
    voteCount: 
      relation: Model.HasManyRelation,
      modelClass: VoteCount,
      join: 
        from: 'content.id',
        to: 'vote_count.content_id'
      
    
  

但我最近(学习并)决定我不需要保留(和更新)一个单独的 vote_count 表,而实际上我可以只查询 vote 表并基本上得到与结果:

SELECT content_id
     , category_id
     , COUNT(*) AS count
  FROM vote
GROUP 
    BY content_id
     , category_id

所以现在我想完全摆脱 vote_count 表。

但这似乎会破坏我的voteCount 关系,因为不再有VoteCount 模型(此处未显示,但它是vote_count 表的对应模型)也不再存在。 (对吧?)

如何在删除 vote_count 表的同时保持 voteCount 关系(以及因此使用它的 VoteCount 模型)?

有没有办法以某种方式在关系中指定,而不是查看具体的表,而应该查看查询的结果?或者是否可以为其定义一个模型类?

如果有帮助,我在 PostgreSQL 中的基础数据库。

【问题讨论】:

欢迎来到 *** 社区,在审核阶段无法注意到您的问题对新用户有很好的格式! (似乎您已经阅读了此内容:***.com/help/how-to-ask)因此,如果有人会帮助您解决问题,请不要忘记投票建议的答案并将问题标记为已回答。或至少按thank you 按钮。 应该没问题,但我不知道你的 ORM。但是“查询的结果”是数据库中的一个视图。 From the Docs :“视图没有物理具体化。相反,每次在查询中引用视图时都会运行查询” 【参考方案1】:

感谢@Belayer。视图正是这个问题的解决方案。

Objection.js supports 在 Model 类中使用视图(而不是表),所以我所要做的就是根据上述查询创建一个视图。

我还使用 Knex 的 migration 策略来创建/版本化我的数据库,虽然它 doesn't (yet) support 创建开箱即用的视图,但我发现您可以只使用原始查询:

module.exports.up = async function(knex) 
  await knex.raw(`
    CREATE OR REPLACE VIEW "vote_count" AS (
      SELECT content_id
          , category_id
          , COUNT(*) AS count
        FROM vote
      GROUP
          BY content_id
          , category_id
    )
  `);
;
module.exports.down = async function(knex) 
    await knex.raw('DROP VIEW "vote_count";');
;

上述迁移步骤替换了我的表 vote_count 以获得等效视图,并且它的 Objection.js 模型类 (VoteCount) 照常工作,无需任何更改,关系 voteCount 也一样Content类。

【讨论】:

以上是关于在删除表格时在 Objection.js 中保留关系图的主要内容,如果未能解决你的问题,请参考以下文章

js添加修改删除表格中数据修改时在表格中直接修改

使用 objection.js 或 knex.js 在 postgres 中的字符串列的 json 数组中查询

在 Objection.js 中按急切结果计数排序记录并实现分页?

Objection.js:所有 where 子句添加后是不是可以用括号括起来?

Objection.js 中的多对多关系

使用 Objection JS 如何使用 withGraphFetched 选择特定列