TL;DR:
alias MyApp.{Repo, Animal}
sql = "SELECT * FROM animals WHERE legs > $1"
params = [2]
%{rows: rows, columns: columns} = Repo.query!(sql, params)
Enum.map(rows, fn row -> Repo.load(Animal, {columns, row}) end)
It was surprisingly difficult to find an easy solution on google for querying your database using raw SQL with ecto and elixir. Above is a short snippet that runs a query with parameters, and then loads the result into an ecto schema.
Repo.query!
is an alias for the underlying db driver you are using, in my case with postgres the function calls Ecto.Adapters.SQL.query
. The result object we get back is a %Postgrex.Result{}
struct that has the rows as a flat two-dimensional array:
%Postgrex.Result{
command: :select,
columns: ["id", "name", "legs"],
rows: [
[1, "cat", 4],
[2, "dog", 4],
],
num_rows: 2,
connection_id: 147,
messages: []
}
but this isn't very nice to work with, so we use the handy Repo.load
function to map our rows into the proper ecto schema (Animal
in the example above) so we can work with them as normal.