【问题标题】:Ecto fragment without parentheses不带括号的 Ecto 片段
【发布时间】:2018-05-13 07:26:21
【问题描述】:

我的 Postgres 表结构:

   id   | stuff                                                                                                                                                                                                        
--------+------------------------------------------------------------
  123   | {"type1": {"ref": "ref_1", "...": "..."}, "type2": {"ref": "ref_1", "...": "..."}}

我想通过ref 查询每种类型的东西,我有一个有效的 SQL 查询:

SELECT * FROM "stuff" AS c0 CROSS JOIN jsonb_each(c0."stuff") AS f1 WHERE value->>'ref' = 'ref_1';

但是使用这个 Ecto 查询:

(from c in Stuff,
  join: fragment("jsonb_each(?)", c.stuff),
  where: fragment("value->>'ref' = ?", ^ref)
)
|> Repo.all

我在 CROSS JOIN 语句中遇到 Postgres 语法错误:

** (Postgrex.Error) ERROR 42601 (syntax_error): syntax error at or near ")"

检查生成的查询:

[debug] QUERY ERROR source="stuff" db=0.3ms
SELECT ... FROM "stuff" AS c0 CROSS JOIN (jsonb_each(c0."stuff")) AS f1 WHERE (value->>'ref' = $1) ["ref_1"]

当我删除 (jsonb_each(c0."stuff")) 周围的外括号时,上述方法有效。

有没有办法让片段生成不带这些括号的查询,还是我必须重新设计查询?

谢谢

【问题讨论】:

标签: postgresql ecto jsonb


【解决方案1】:

似乎 Ecto 总是将 join 子句括在括号中,这通常没问题。不幸的是,它不包括某些调用,例如上面的 jsonb_each。对于这种情况,这里有一个 wiki:The parentheses rules of PostgreSQL, is there a summarized guide?

链接的原始 sql 示例的答案要少得多,似乎可以很好地进行此查询并返回预期的结构。

sql = "SELECT * FROM "stuff" AS c0 CROSS JOIN jsonb_each(c0."stuff") AS f1 WHERE value->>'ref' = 'ref_1';"
result = JsonbTest.Repo.query!(sql)
Enum.map(result.rows, &JsonbTest.Repo.load(StuffStruct, {result.columns, &1}))

【讨论】:

  • 这就是我所采用的方法,但是,我真的希望有更多的 Ecto 方法来解决这个问题。
【解决方案2】:

这是ecto中的一个错误,已在此处修复https://github.com/elixir-ecto/ecto/issues/2537

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-07
    • 1970-01-01
    • 2021-06-29
    • 2021-08-03
    • 2021-10-14
    • 1970-01-01
    相关资源
    最近更新 更多