Description
I'm trying to create insert a series of entries at once using Multi.insert_all
(Multiple :experiment_status
need to be created after their associated :experiment
is created).
multi =
Multi.new()
|> Multi.insert(:experiment, changeset_experiment)
|> Multi.merge(fn %{experiment: experiment} ->
Multi.new()
|> Multi.insert_all(
:experiment_statuses,
ExperimentStatus,
ExperimentStatus.multi_changeset_from_experiment(experiment)
)
end)
I believe that I've filled out every field of the model in each changeset/map to be inserted (except for the id
field of the :experiment_status
itself, of course):
def multi_changeset_from_experiment(experiment) do
for variant <- 1..experiment.num_variants,
chain <- 1..experiment.num_chains,
realization <- 1..experiment.num_realizations do
%{
experiment_id: experiment.id,
variant: variant,
chain: chain,
realization: realization,
status: 0,
inserted_at: Ecto.DateTime.utc(),
updated_at: Ecto.DateTime.utc()
}
end
end
The migration used to create the :experiment_status
table:
create table(:experiment_statuses) do
add(:experiment_id, references("experiments", on_delete: :delete_all))
add(:variant, :integer, null: false)
add(:chain, :integer, null: false)
add(:realization, :integer, null: false)
add(:status, :integer, default: 0, null: false)
timestamps()
end
However, I get an error upon Repo.transaction(multi)
, which is "Cell-wise default values are not supported on INSERT statements by SQLite".
I took a look at the source code of sqlite_ecto2
. The error is on line 155 of lib/sqlite_ecto/connection.ex
but I couldn't easily understand this error, since it doesn't pinpoint the exact cause:
** (ArgumentError) Cell-wise default values are not supported on INSERT statements by SQLite
(sqlite_ecto2) lib/sqlite_ecto/connection.ex:155: anonymous fn/2 in Sqlite.Ecto2.Connection.insert_each/2
(sqlite_ecto2) lib/sqlite_ecto/connection.ex:871: Sqlite.Ecto2.Connection.intersperse_reduce/5
(sqlite_ecto2) lib/sqlite_ecto/connection.ex:146: anonymous fn/2 in Sqlite.Ecto2.Connection.insert_all/2
(sqlite_ecto2) lib/sqlite_ecto/connection.ex:871: Sqlite.Ecto2.Connection.intersperse_reduce/5
(sqlite_ecto2) lib/sqlite_ecto/connection.ex:145: Sqlite.Ecto2.Connection.insert_all/2
(sqlite_ecto2) lib/sqlite_ecto/connection.ex:132: Sqlite.Ecto2.Connection.insert/6
(sqlite_ecto2) lib/sqlite_ecto.ex:37: Sqlite.Ecto2.insert_all/7
(ecto) lib/ecto/repo/schema.ex:52: Ecto.Repo.Schema.do_insert_all/7
I don't think I'm asking for any default value... except for maybe the ID field of :experiment_status
, which should be automatically generated.
Should I just try to do without insert_all
on a list of raw maps, and instead create and insert changesets one by one? That would seem to be a quite unwiedly way to use Ecto.Multi
. I just wonder what caused the issue and whether Ecto's insert_all
could be used at all with SQLite.