【问题标题】:Elixir ecto: check if postgresql map column has keyElixir ecto:检查 postgresql 映射列是否有键
【发布时间】:2016-06-19 03:27:31
【问题描述】:

要使用 json/jsonb 数据类型 ecto 建议 to use fragments

就我而言,我必须使用 PostgreSQL ? 运算符来查看地图是否有这样的键,但是它会变成这样:

where(events, [e], e.type == 1 and not fragment("???", e.qualifiers, "?", "2"))

当然,fragment 将 PostgreSQL ? 读取为占位符。如何检查地图是否有这样的键?

【问题讨论】:

    标签: postgresql elixir ecto


    【解决方案1】:

    您需要将中间的? 转义,并将总共三个参数传递给fragment

    fragment("? \\? ?", e.qualifiers, "2")
    

    演示:

    iex(1)> MyApp.Repo.insert! %MyApp.Food{name: "Foo", meta: %{price: 1}}
    iex(2)> MyApp.Repo.insert! %MyApp.Food{name: "Foo", meta: %{}}
    iex(3)> MyApp.Repo.all from(f in MyApp.Food, where: fragment("? \\? ?", f.meta, "price"))
    [debug] SELECT f0."id", f0."name", f0."meta", f0."inserted_at", f0."updated_at" FROM "foods" AS f0 WHERE (f0."meta" ? 'price') [] OK query=8.0ms
    [%MyApp.Food{__meta__: #Ecto.Schema.Metadata<:loaded>, id: 1,
      inserted_at: #Ecto.DateTime<2016-06-19T03:51:40Z>, meta: %{"price" => 1},
      name: "Foo", updated_at: #Ecto.DateTime<2016-06-19T03:51:40Z>}]
    iex(4)> MyApp.Repo.all from(f in MyApp.Food, where: fragment("? \\? ?", f.meta, "a"))
    [debug] SELECT f0."id", f0."name", f0."meta", f0."inserted_at", f0."updated_at" FROM "foods" AS f0 WHERE (f0."meta" ? 'a') [] OK query=0.8ms
    []
    

    我不确定这是否记录在任何地方,但我从this 测试中找到了方法。

    【讨论】:

    • 是的,我也发现了,必须先升级ecto才能使用它,你能解释一下为什么要加倍`\`吗?
    • 这是因为 Elixir 也使用 \ 作为转义字符,所以我们需要对其进行双重转义以确保 Postgres 得到 1 个 \。你也可以使用~S:~S|? \? ?| == "? \\? ?"
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-20
    • 2016-10-26
    • 2018-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多