🐜 Antz

Declarative CSV-to-ActiveRecord importer with dependency resolution

Import structured CSV data into your Rails (or plain ActiveRecord) app β€” safely, clearly, and in the right order.


🧩 Why Antz?

Ever needed to seed a database from CSVs…
but your products depend on categories, which depend on vendors?
And you don’t want to write fragile, one-off scripts?

Antz lets you:

  • Declare what data goes where β€” like a recipe.
  • Map and transform CSV columns to model attributes.
  • Automatically resolve dependencies (e.g., import users before orders).
  • Batch-process large files efficiently.
  • Dry-run safely before touching your DB.

All with a clean, readable Ruby DSL using the #table method.


πŸš€ Quick Start

1. Add to your Gemfile

gem "antz"

Then run:

bundle install

βœ… Requires Ruby β‰₯ 3.2 and ActiveRecord β‰₯ 6.0.


2. Configure (e.g. in Rails)

# config/initializers/antz.rb

Antz.configure do |c|
  c.base_dir = Rails.root.join("data", "csv_imports")  # where your CSVs live
  c.batch_size = 500                                   # default: 200
end

3. Define Your Import Plan

import = Antz.define do
  table :categories do
    map :id
    map :name
  end

  table :products, depends_on: :categories do
    map :name
    map :category_id
    map(:price_cents) { |v| v.to_i * 100 }  # transform on the fly
  end

  table :users do
    map :full_name, to: :name
    map :email
    map(:age) { |v| v&.to_i }
  end
end

πŸ’‘ CSV filenames default to pluralized table names (e.g., products.csv).
You can override with file: "my_custom_file.csv".


4. Run It

# Preview what would happen (no DB writes)
import.run(dry_run: true)

# Actually import
import.run

βœ… Handles upsert_all (PostgreSQL/MySQL) when possible. Falls back to insert_all.


πŸ“ Expected CSV Structure

Each file must have headers matching your source column names:

categories.csv

id,name
1,Fruits
2,Vegetables

products.csv

name,category_id,price_cents
Apple,1,99
Carrot,2,59

πŸ”Œ Advanced Usage

Custom Model Name

table :items, model: Product do
  map :title, to: :name
end

Skip Upsert (Insert Only)

table :logs, on_duplicate: :ignore do
  map :message
end

Absolute File Path

table :events, file: "/mnt/data/events_export.csv" do
  map :timestamp
end

πŸ§ͺ Testing & Development

Antz is thoroughly tested with RSpec. To run the suite:

bin/setup
bundle exec rspec

Fixtures use in-memory SQLite β€” no external DB needed.


πŸ“„ License

MIT Β© 2025 Ilmir Karimov


πŸ’‘ Inspired by

  • The pain of one-off CSV import scripts
  • The need for reproducible, maintainable data bootstrapping

πŸ‘‰ Found a bug? Have an idea?
Open an issue or PR on GitHub!