2016-03-16 12 views
7

Jestem bardzo nowy w świecie frameworków Elixir i Phoenix. Próbuję wykonać samouczek TheFireHoseProject, ale mam problem z zapytaniem o surowy SQL z Ecto. Samouczek mówi, że to powinno działać:Surowy SQL z Ecto

defmodule Queries do 
def random do 
    query = Ecto.Adapters.Postgres.query(
    Repo, 
    "SELECT id, saying, author from quotes ORDER BY RANDOM() LIMIT 1", 
    []) 
    %Postgrex.Result{rows: [row]} = query 
    {id, saying, author} = row 
    %Splurty.Quote{id: id, saying: saying, author: author} 
end 
end 

Dostaję błąd runtime że Ecto.Adapters.Postgres.query nie istnieje (funkcję niezdefiniowany).

Próbowałem przeszukać dokumentację Ecto i odkryłem, że może istnieć funkcja o nazwie run_query, ale ona również nie działa.

Myślę, że używam Ecto 1.1.4 i nie znalazłem żadnych dobrych (aktualnych) próbek tego, jak mogę zapytać o surowy SQL z Ecto.

Link do firehoseproject jest: http://phoenix.thefirehoseproject.com/

Odpowiedz

9
alias Ecto.Adapters.SQL 

querystring = "..." 

result = SQL.query(Repo, querystring , []) 

a następnie można dodać wynik do listy na przykład tak:

list = [] 

case result do 
    {:ok, columns} -> 
      list = for item <- columns.rows do 
       List.first(item) 
      end 
    _ -> IO.puts("error") 
end 
+1

Zapytanie wydaje się działać teraz, ale mam problemy mapowanie wyników do mojego modelu obiektowego (Quote). Myślę, że to tylko ja uczę się ogólnie eliksiru. –

9

Jeśli wszystko czego potrzebujesz to po prostu dodaj surowy SQL inaczej normalne zapytanie Ecto można użyć fragment/1:

from q in Quote, order_by: fragment("RANDOM()"), limit: 1 

To często wystarczy i jest łatwiejsze w obsłudze. Zwykle można użyć fragmentu/1 w dowolnej części zapytania Ecto. Dla jeszcze ładniejszy użytku, można zdefiniować makro, które pozwoli Ci ładnie pasuje do ekto za DLS:

defmodule QueryHelpers do 
    defmacro random() do 
    quote do 
     fragment("RANDOM()") 
    end 
    end 
end 

A później wykorzystać go:

import QueryHelpers 
from q in Quote, order_by: random(), limit: 1 
+0

Zasadniczo rozwiązałoby to mój obecny problem, ale ze względu na uczenie się chcę zobaczyć, jak mogę wykonać kompletny raw sql z ecto. W każdym razie, jest to również bardzo miłe wiedzieć i prawdopodobnie przyda się w przyszłości, dzięki! –