AshCsvInterchange

CI Hex version badge Hexdocs badge License: Apache 2.0

An Ash extension for declaring CSV-importable and CSV-exportable resources via a Spark DSL.

Resources that use the extension expose:

Installation

def deps do
  [
    {:ash_csv_interchange, "~> 0.1.0"}
  ]
end

Usage

Configure the app that owns your CSV resources and the domains to search:

config :ash_csv_interchange, otp_app: :my_app
config :my_app, AshCsvInterchange, domains: [MyApp.Crm]

Add the extension to a resource and declare its CSV types:

defmodule MyApp.Crm.Contact do
  use Ash.Resource,
    domain: MyApp.Crm,
    extensions: [AshCsvInterchange]

  csv_imports do
    csv_import :contacts do
      label "Contacts"
      headers required: ["external_id", "first_name"], optional: ["last_name"]
      upsert_action :import_from_csv
    end
  end

  csv_exports do
    csv_export :contacts do
      label "Contacts"
      read_action :for_csv_export
      columns [
        {"external_id", :external_id},
        {"first_name", :first_name},
        {"last_name", :last_name}
      ]
    end
  end

  # ... an upsert action, a keyset-paginated read action, attributes and
  # an identity. See the getting started guide for the full resource.
end

Then import and export:

# Check a file without writing anything, then commit it.
{:ok, report} = AshCsvInterchange.import_csv(:contacts, csv)
{:ok, report} = AshCsvInterchange.import_csv(:contacts, csv, mode: :commit)

# Stream a large file; rows are written as the stream is consumed.
{:ok, %{outcomes: outcomes}} =
  AshCsvInterchange.stream_import(:contacts, {:path, "/tmp/contacts.csv"}, mode: :commit)

# Export as one binary, or as a stream of chunks.
{:ok, csv} = AshCsvInterchange.export_csv(:contacts)
{:ok, stream} = AshCsvInterchange.stream_export(:contacts, batch_size: 500)

Guides

The same guides are in the online documentation.

Development

Requires Elixir / OTP as pinned in .tool-versions.

mix deps.get
mix check        # full local quality suite
mix test         # just the tests
mix format       # format all files

Or use the included devcontainer — opens with VS Code or any devcontainer-compatible editor and sets up Elixir + asdf automatically.

Releases

Releases are automated via git_ops and conventional commits. To cut a release:

mix git_ops.release
git push && git push --tags

Then create a GitHub Release from the tag — the release.yml workflow publishes to Hex on your behalf.

License

Apache 2.0. See LICENSE.


This repository was generated from team-alembic/elixir_package_template.