Snowflex.MigrationGenerator (Snowflex v1.2.1)

View Source

Provides functionality to automatically generate and run migrations based on Ecto schemas or raw table definitions.

This module is particularly useful when you need to:

  • Test Snowflake schemas using a local database
  • Dynamically switch between Snowflake and local database implementations
  • Generate migrations from both Ecto schemas and raw table definitions

Usage

First, create a wrapper around your Repo that uses this module:

defmodule MyApp.Repo do
  defmacro __using__(_opts) do
    [select_repo(__CALLER__.module), add_schema_helper()]
  end

  defp select_repo(caller_mod) do
    config = Application.get_env(:my_app, caller_mod)

    if config[:use_local_db?] do
      quote do
        use Ecto.Repo,
          otp_app: :my_app,
          adapter: Ecto.Adapters.Postgres

        alias Snowflex.MigrationGenerator
        require Snowflex.MigrationGenerator

        @spec generate_migrations(list(module())) :: :ok
        def generate_migrations(modules) do
          MigrationGenerator.generate_migrations(__MODULE__, modules)
        end
      end
    else
      quote do
        use Ecto.Repo, otp_app: :my_app, adapter: Snowflex
      end
    end
  end

  defp add_schema_helper do
    quote do
      def connection_value(key, default \ nil) do
        :my_app
        |> Application.get_env(__MODULE__, [])
        |> Keyword.get(key, default)
      end
    end
  end
end

Then you can use it in your application in two ways:

Using Ecto Schemas

defmodule MyApp.Data.User do
  use Ecto.Schema
  schema "users" do
    field :name, :string
    field :email, :string
    timestamps()
  end
end

# Generate migrations for schemas
MyApp.Repo.generate_migrations([
  MyApp.Data.User,
  MyApp.Data.Post
])

We use generate_migrations in our test_helper.exs file to ensure the database is setup for testing. Note that this does create a new local DB for each Snowflake Repo you declare in your application.

Using Raw Table Definitions

# Generate migrations for raw table definitions
MyApp.Repo.generate_migrations([
  {MyApp.Data.CustomTable,
   {"SCHEMA.TABLE_NAME",
    [
      id: :string,
      name: :string,
      created_at: :utc_datetime
    ], []}}
])

Configuration

To use this module, you'll need to configure your application to switch between Snowflake and local database:

# config/config.exs
config :my_app, MyApp.Repo

# config/test.exs
config :my_app, MyApp.Repo,
  use_local_db?: true,
  adapter: Ecto.Adapters.Postgres

Arguments

  • repo - The Ecto.Repo module to use for migrations
  • modules - A list of either:
    • Ecto.Schema modules
    • Tuples of {module, {source, fields, primary_key}} where:
      • module is the module name
      • source is the table name
      • fields is a keyword list of field names and types
      • primary_key is a list of primary key field names

Returns

  • :ok when migrations are successfully generated and run

Summary

Functions

generate_migrations(repo, modules)

(macro)