Arcana.Graph.Migration (Arcana v3.0.1)

Copy Markdown View Source

Versioned migrations for Arcana's GraphRAG tables.

GraphRAG is optional, so it carries its own version separate from Arcana.Migration. Install it the same way:

defmodule MyApp.Repo.Migrations.AddArcanaGraph do
  use Ecto.Migration

  def up, do: Arcana.Graph.Migration.up(dimensions: 384)
  def down, do: Arcana.Graph.Migration.down()
end

Upgrading needs no new DDL, only another migration calling up/1.

Options

  • :version - target version (defaults to the latest)
  • :dimensions - embedding dimensions for arcana_graph_entities.embedding. Must match Arcana.Embedder.dimensions/1 for the embedder you run
  • :prefix - Postgres schema to install into (defaults to the connection's current schema)
  • :create_schema - whether to create :prefix when it is missing (defaults to true, ignored without a prefix)

Adoption

Installs predating this module have graph tables but no recorded version. Version 1 converges them: it creates only what is absent and adds only the columns and indexes a later release introduced. The one thing it drops is a unique index whose shape is wrong: see "What converge verifies" below.

Where the version is recorded

The applied version is stored as the Postgres comment on arcana_graph_entities, as exactly arcana_graph:<n>:

SELECT obj_description('arcana_graph_entities'::regclass);

Arcana owns that comment. Two consequences worth knowing before you point schema-documentation or data-catalog tooling at this table:

  • recording a version replaces whatever comment is there, so a description you wrote on arcana_graph_entities is lost on the next migration
  • a comment Arcana doesn't recognise reads as version 0, the same as a fresh install, so up/1 re-runs the converge path (idempotent, and harmless) while down/1 declines to drop anything

Comment on any other table freely. Only arcana_graph_entities is reserved.

What converge verifies

Adoption creates only what is absent, so most objects are checked by name alone. Three are verified against the catalog and corrected when they differ, because being merely present isn't enough:

  • arcana_documents.collection_id's delete rule, since older templates emitted ON DELETE SET NULL
  • the embedding column's dimension, which is compared against :dimensions rather than altered
  • the unique indexes on arcana_graph_entities(name, collection_id) and arcana_graph_entity_mentions(entity_id, chunk_id), since create_if_not_exists matches on the index name and an older template may have created one with a different shape

Everything else is create-if-absent. For the plain indexes that is deliberate: a differing one costs performance, not correctness.

Version history

  • 1 - entities, relationships, mentions and communities, including the entity-mention unique index and communities.summary_fingerprint that earlier releases shipped as separate upgrade migrations

Summary

Functions

The latest graph version this release of Arcana knows how to migrate to.

Migrates down to :version, or removes the graph tables entirely.

The graph version recorded in the database, or 0 when GraphRAG has never been installed.

Migrates up to :version, or to the latest version.

Functions

current_version()

The latest graph version this release of Arcana knows how to migrate to.

down(opts \\ [])

Migrates down to :version, or removes the graph tables entirely.

recorded_version(repo \\ nil, opts \\ [])

The graph version recorded in the database, or 0 when GraphRAG has never been installed.

Pass a repo when calling this outside a migration; inside one it defaults to the migration's own repo. Pass :prefix to read a version recorded in a Postgres schema other than the current one.

Both arguments default, so options must be given with a repo: recorded_version(MyApp.Repo, prefix: "tenant_a"). A lone keyword list would bind to the repo argument.

up(opts \\ [])

Migrates up to :version, or to the latest version.