50

upsert 要件があるため、postgres ストアド プロシージャを呼び出すか、共通テーブル式を使用する必要があります。また、パスワードに pgcrypto exgtension を使用しており、postgres 関数 (パスワードをエンコード/デコードするための「crypt」など) を使用したいと考えています。

しかし、Ecto で生の SQL を部分的または全体的に操作する方法が見つかりません。ecto は elixir dsl のみをサポートし、dsl が十分でない場合に生の SQL へのシェルアウトを許可しないことを意図していますか?

アダプターを介してクエリできることがわかりました(ロケットはアプリの名前です)

q = Ecto.Adapters.Postgres.query(Rocket.Repo,"select * from users limit 1",[])

しかし、これをモデルに取得する方法がわかりません。私は elixir が初めてで、Ecto.Model.Schem を使用できるはずです。schema /3 しかし、これは失敗します

Rocket.User.__schema__(:load,q.rows |> List.first,0)
** (FunctionClauseError) no function clause matching in Rocket.User.__schema__/3    
4

8 に答える 8

45

Postgres を使用する Ecto 2.0 (ベータ版) では、Ecto.Adapters.SQL.query()( current docs2.0-beta2 docs ) を使用して任意の SQL を実行できます。行自体のリスト (" rows") に加えて、たまたま列名のリスト (" ") を返しますcolumns

以下の例では、私は

  1. パラメータなしでカスタム クエリを実行し、
  2. 結果の列名を文字列からアトムに変換し、
  3. それらを結果の各行と結合し、それをKernel.struct()で構造体にマップします

(おそらくquery()バージョンを実行して (強打なしで!)、 を確認することをお勧めします{ok, res}。)

qry = "SELECT * FROM users"
res = Ecto.Adapters.SQL.query!(Repo, qry, []) # 1

cols = Enum.map res.columns, &(String.to_atom(&1)) # 2

roles = Enum.map res.rows, fn(row) ->
  struct(MyApp.User, Enum.zip(cols, row)) # 3
end
于 2016-04-20T00:09:03.237 に答える
7

Ecto.Adapters.SQL.query/4に加えて、クエリ式をデータベースに送信するために使用できるEcto.Query.API.fragment/1もあります。たとえば、Postgres の配列関数を使用するには、次のようにしarray_upperます。

Ecto.Query.where([x], fragment("array_upper(some_array_field, 1)]" == 1)
于 2015-08-20T21:05:38.983 に答える
-5

少なくとも ecto 4.0 では、アダプターを使用してクエリを実行し、結果を Ecto.Model にフィードできます。スキーマ/3:

q = Ecto.Adapters.Postgres.query(Rocket.Repo,"select * from users limit 1",[])
Rocket.User.__schema__(:load,q.rows |> List.first,0)
于 2015-01-05T18:10:09.213 に答える