# Script for populating the database. You can run it as: # # mix run priv/repo/seeds.exs # # Inside the script, you can read and write to any of your # repositories directly: # # ActionRequestsDemo.Repo.insert!(%ActionRequestsDemo.SomeSchema{}) # # We recommend using the bang functions (`insert!`, `update!` # and so on) as they will fail if something goes wrong. alias ActionRequestsDemo.Repo alias ActionRequestsDemo.ActionRequests.ActionRequest # Configuration total_records = 1_000_000 # SQLite has a max parameter limit of 32766 # With 7 fields per record, max is ~4681 records per batch # Using 4000 to be safe batch_size = 4_000 num_batches = div(total_records, batch_size) IO.puts("Seeding #{total_records} action requests in #{num_batches} batches of #{batch_size}...") IO.puts("Started at: #{DateTime.utc_now()}") statuses = ["resolved", "unresolved"] # Helper function to generate a single record generate_record = fn -> patient_name = Faker.Person.name() status = Enum.random(statuses) assigned_user_id = if :rand.uniform() > 0.3, do: Enum.random(1..5), else: nil days_ago = :rand.uniform(365) inserted_at = DateTime.utc_now() |> DateTime.add(-days_ago * 24 * 3600, :second) |> DateTime.truncate(:second) delivery_scheduled_at = if :rand.uniform() > 0.4 do days_ahead = :rand.uniform(14) NaiveDateTime.utc_now() |> NaiveDateTime.add(days_ahead * 24 * 3600, :second) |> NaiveDateTime.truncate(:second) else nil end %{ id: Ecto.UUID.generate(), patient_name: patient_name, status: status, assigned_user_id: assigned_user_id, delivery_scheduled_at: delivery_scheduled_at, inserted_at: inserted_at, updated_at: inserted_at } end # Process batches sequentially (SQLite doesn't handle concurrent writes well) start_time = System.monotonic_time(:millisecond) Enum.each(1..num_batches, fn batch_num -> # Generate batch of records records = for _i <- 1..batch_size, do: generate_record.() # Insert batch in a single transaction {count, _} = Repo.insert_all(ActionRequest, records) if rem(batch_num, 10) == 0 do elapsed = div(System.monotonic_time(:millisecond) - start_time, 1000) progress = batch_num * batch_size rate = if elapsed > 0, do: div(progress, elapsed), else: 0 IO.puts("Progress: #{progress}/#{total_records} (#{div(progress * 100, total_records)}%) - #{rate} records/sec") end count end) end_time = System.monotonic_time(:millisecond) elapsed_seconds = div(end_time - start_time, 1000) records_per_second = div(total_records, max(elapsed_seconds, 1)) IO.puts("\n✓ Successfully seeded #{total_records} action requests!") IO.puts("Total time: #{elapsed_seconds} seconds (#{records_per_second} records/sec)") IO.puts("Finished at: #{DateTime.utc_now()}")