INSERT … SELECT in Ecto using Ecto.Query

I’m attempting to replicate an INSERT … SELECT in Ecto. This appears to be supported by both postgres and mysql (I’m using postgres). I’ve got this working in SQL, but trying to recreate in Ecto.Query.

I created an ecto query that returns the data I want, and tried passing it to insert or insert_all and both seemed to cause errors.

Is there a supported method to do this, or is the official answer, “just use sql”?

I found this post that didn’t really answer the question from Aug 2018: Execute Insert_all from a select

Can you share the working sql query?

I suspect you might be looking for https://hexdocs.pm/ecto/Ecto.Query.html#subquery/2

A very simplified example (but I’m only adding more columns):

INSERT INTO fake_table (name, inserted_at, updated_at) SELECT name, now(), now() FROM other_fake_table;

I’m not sure if this is the right syntax but maybe you can do something along the lines of

Repo.insert_all(
  SomeSchema, [
    [id: from(o in OtherSchema, select: o.id)]
  ]
)

insert_all does support using a query, similar to what you’ve suggested, but only to return a single value. It doesn’t appear to build/use the INSERT INTO … SELECT statement.

The keys of the entries are the field names as atoms and the value should be the respective value for the field type or, optionally, an Ecto.Query that returns a single entry with a single value.

https://hexdocs.pm/ecto/Ecto.Repo.html#c:insert_all/3

Hey! I forgot about this reply :blush:

Well, thats a bummer. How did you ended up solving this?

In the end: SQL.

I may try to submit a feature to ecto.

Yeah, figured that might be the case.

Found the PR that implemented the suporte for single return subquery on insert_all.
Maybe I will have a look this weekend to see if its easy to implement this.