如何通过 ecto 将从 STR 返回的集合检索到模型中?
How can I retrieve the set returned from a STR into a model via ecto?
我在 postgreSQL 上有一组返回函数,例如
CREATE FUNCTION set_ret_func(foo int, bar int)
RETURNS TABLE(total bigint, result bigint) AS $$
SELECT a.val + as total, b.val + as result
FROM a, b
$$ LANGUAGE SQL;
此函数为我提供了一个 "flexible view",我可以轻松调用它:
SELECT * from set_ret_func('30'::int, '89'::int)
环顾四周,我发现可以通过 Ecto.Repo 执行类似
的操作来调用多态关联
from( x in {"table_name", Model}, select: x.total )
|> Repo.all
这让我想知道我是否可以使用 Ecto.Query 或 Ecto.Query 中的 fragment/1。from/2 中的 API 所以我能够将我的集合返回函数调用到架构中(它们都将在 column_name 上匹配),根据我的想象,它看起来像这样:
from( srf in {fragment("set_ret_func(?::int, ?::int)", var1, var2), Model},
select: srf.total)
是否有调用此 STR 并将其转换为模型的实际方法?
老实说,最简单的方法是 Ecto.Adapters.SQL.query
。您仍然可以将其加载到模型中。这是一个应该大致正确的快速片段:
with {:ok, %{columns: cols, rows: rows}} <- Ecto.Adapters.SQL.query(Repo, "SELECT * FROM set_rec_func(?,?)", [var1, var2])
fields = Enum.map(cols, &String.to_existing_atom/1) do
for row <- rows, values = Enum.zip(fields, rows) do
struct(Model, values) |> Ecto.put_meta(state: :loaded)
end
end
尽管这并不是您的 ecto 查询试图做的,select 只是一个字段而不是整个模型。实际上,在 Ecto 中并没有那么多的模型魔术。所有真正的魔法都发生在 Ecto.Query API 和 Ecto.Changeset API 中。事实上,为了防止将来出现混淆,Ecto 2.0(几天之内)将完全删除 "Model" 这个词。它们都是与某些模式元数据相关联的普通结构。
我在 postgreSQL 上有一组返回函数,例如
CREATE FUNCTION set_ret_func(foo int, bar int)
RETURNS TABLE(total bigint, result bigint) AS $$
SELECT a.val + as total, b.val + as result
FROM a, b
$$ LANGUAGE SQL;
此函数为我提供了一个 "flexible view",我可以轻松调用它:
SELECT * from set_ret_func('30'::int, '89'::int)
环顾四周,我发现可以通过 Ecto.Repo 执行类似
的操作来调用多态关联from( x in {"table_name", Model}, select: x.total )
|> Repo.all
这让我想知道我是否可以使用 Ecto.Query 或 Ecto.Query 中的 fragment/1。from/2 中的 API 所以我能够将我的集合返回函数调用到架构中(它们都将在 column_name 上匹配),根据我的想象,它看起来像这样:
from( srf in {fragment("set_ret_func(?::int, ?::int)", var1, var2), Model},
select: srf.total)
是否有调用此 STR 并将其转换为模型的实际方法?
老实说,最简单的方法是 Ecto.Adapters.SQL.query
。您仍然可以将其加载到模型中。这是一个应该大致正确的快速片段:
with {:ok, %{columns: cols, rows: rows}} <- Ecto.Adapters.SQL.query(Repo, "SELECT * FROM set_rec_func(?,?)", [var1, var2])
fields = Enum.map(cols, &String.to_existing_atom/1) do
for row <- rows, values = Enum.zip(fields, rows) do
struct(Model, values) |> Ecto.put_meta(state: :loaded)
end
end
尽管这并不是您的 ecto 查询试图做的,select 只是一个字段而不是整个模型。实际上,在 Ecto 中并没有那么多的模型魔术。所有真正的魔法都发生在 Ecto.Query API 和 Ecto.Changeset API 中。事实上,为了防止将来出现混淆,Ecto 2.0(几天之内)将完全删除 "Model" 这个词。它们都是与某些模式元数据相关联的普通结构。