francois
How to run a SELECT WHERE column IN (...) query?
Hi all!
I don’t know what to do to make Ecto happy to run the following query:
sql = "" <>
"SELECT chat_user_notification_keys.key " <>
"FROM chat_user_rooms " <>
"JOIN chat_user_notification_keys ON chat_user_notification_keys.user_id = chat_user_rooms.user_id " <>
"JOIN users ON users.id = chat_user_rooms.user_id " <>
"JOIN chat_rooms ON chat_rooms.id = chat_user_rooms.room_id " <>
"WHERE chat_rooms.id_ref = $1::text::uuid " <>
" AND users.slug NOT IN ($2)"
case Ecto.Adapters.SQL.query(BusChatWeb.Repo, sql, [room_id, user_slugs_who_are_present]) do
{:ok, %{num_rows: num_keys, rows: keys}} ->
case num_keys do
0 -> # ...
_ -> # ...
end
end
Currently, I get the following error message:
** (ArgumentError) Postgrex expected a binary, got []. Please make sure the value you are passing matches the definition in your table or in your query or convert the value accordingly.
[debug] QUERY ERROR db=9.9ms
SELECT chat_user_notification_keys.key FROM chat_user_rooms JOIN chat_user_notification_keys ON chat_user_notification_keys.user_id = chat_user_rooms.user_id JOIN users ON users.id = chat_user_rooms.user_id JOIN chat_rooms ON chat_rooms.id = chat_user_rooms.room_id WHERE chat_rooms.id_ref = $1::text::uuid AND users.slug NOT IN ($2) ["afe13f89-7819-43d9-9bb8-b4ba38a2ddac", []]
(ecto) /Users/francois/Projects/chat_web/deps/postgrex/lib/postgrex/type_module.ex:717: Ecto.Adapters.Postgres.TypeModule.encode_params/3
(postgrex) lib/postgrex/query.ex:45: DBConnection.Query.Postgrex.Query.encode/3
(db_connection) lib/db_connection.ex:1071: DBConnection.describe_run/5
(db_connection) lib/db_connection.ex:1142: anonymous fn/4 in DBConnection.run_meter/5
(db_connection) lib/db_connection.ex:1199: DBConnection.run_begin/3
(db_connection) lib/db_connection.ex:584: DBConnection.prepare_execute/4
(ecto) lib/ecto/adapters/postgres/connection.ex:93: Ecto.Adapters.Postgres.Connection.execute/4
(ecto) lib/ecto/adapters/sql.ex:243: Ecto.Adapters.SQL.sql_call/6
(chat_web) lib/chat_web/repo.ex:117: ChatWeb.Repo.find_notifiable_keys/2
The problem is related to the $2 parameter: it’s a list in Elixir-land. How can I convert/cast a list to something Ecto will be happy?
Thanks!
Most Liked
francois
Thanks @OvermindDL1. The UUIDs are coming straight from the UI layer. I kept them as strings, because that makes it easy to inspect the value from anywhere in the stack.
I finally found a solution to my problem by reusing the ANY operator. My original SQL query is now:
-- as before
AND NOT users.slug = ANY ($2::text[])
This works and satisfies me.
Thanks!
zambal
You need to dump the string UUID first to a binary like this:
{:ok, bin} = Ecto.UUID.load(room_id)
Now you can use the binary UUID directly in your query like this:
where: chat_rooms.id_ref == ^bin
Note that if you use an Ecto schema, you don’t need to do all this manual casting and dumping.
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance









