I need to include multiple legacy migrations (written in plain SQL) in an ecto migration.
The current legacy application relies heavily on custom ENUM types in postgresql.
When I try to run the existing migrations (concatenated as a string) via execute my_combined_sql I will get the error cannot insert multiple commands into a prepared statement.
The minimal example of a failing SQL file is:
CREATE TYPE UState AS ENUM ("state1", "state2");
CREATE TABLE IF NOT EXISTS Users
(userEmail VARCHAR(320) NOT NULL PRIMARY KEY,
state UState NOT NULL);
Is there a way to do this with ecto, or do I need another process to apply the legacy migrations to the database?
By default Ecto uses prepared statements (this is like a precompiled form of the statement which is the cached so that reuse is materially faster).
There is an option prepare: :unnamed which I think goes on the Repo configuration (its a Postgrex adapter option) but I can’t recall and I’m in China this week so googling isn’t an option.
Sorry its an incomplete answer but hopefully thats enough to get you started…
Hey @kip
Thanks for the input and taking the time.
In principle this shouldn’t be a problem to execute the statements one by one. This specific migration does not need to execute fast.
Just to clearify: I could split my SQL statements into a list and then call execute SUBQUERY1, execute SUBQUERY2, etc. in the same up/down statement, right?
Now I’ve paid a little more attention… I believe the issue is that you can’t create the Enum in the same transaction as using it.
Typically what I do in this case is actually prepare two migrations: one to create the Enum and the other to create the table.
However should be perfectly ok to:
def up do
execute "CREATE TYPE UState AS ENUM (\"state1\", \"state2\");"
execute """
CREATE TABLE IF NOT EXISTS Users
(userEmail VARCHAR(320) NOT NULL PRIMARY KEY,
state UState NOT NULL);
"""
end