Skip to content

"Cell-wise default values are not supported on INSERT statements by SQLite" error upon trying to run insert_all #231

@x-ji

Description

@x-ji

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions