Ash DataLayer for Apache AGE graph database.
Stores Ash resources as vertices in an AGE graph within PostgreSQL. Uses the existing Ecto.Repo connection pool — no new database driver. All dynamic values use parameterized queries for safety.
DSL
use Ash.Resource,
data_layer: AshAge.DataLayer
age do
graph :my_graph
repo MyApp.Repo
label :MyLabel # optional, defaults to the module's short name
skip [:computed] # optional, attributes excluded from AGE properties
sensitive [:ssn] # optional, classified attributes (binary-storage or skipped)
rls_guc "myapp.tenant_id" # optional, :attribute-only DB-enforced RLS backstop
# tenant_graph {MyApp.Graphs, :for_tenant, []} # optional, :context graph-name override
edge :related_to do
label :RELATES_TO
direction :outgoing
destination MyApp.OtherResource
end
endCapabilities
Supports :read, :create, :update, :destroy, :bulk_create, :filter
(eq/not_eq/gt/lt/gte/lte/in/is_nil, boolean and nested expressions),
:sort, :limit, :offset, :transact, :multitenancy (:attribute and
:context), :composite_primary_key, and :changeset_filter. Not supported:
:upsert, aggregates, and lateral joins. One subtlety: binary-storage
attributes are unsortable (can?({:sort, :binary}) is false) because
the stored $age64$-tagged base64 form is not byte-order-preserving —
sorting on one raises Ash.Error.Query.UnsortableField at query build.
Summary
Functions
Bulk-creates a batch of changesets via key-set-grouped UNWIND ... CREATE.
Functions
Bulk-creates a batch of changesets via key-set-grouped UNWIND ... CREATE.
A batch is fanned into one SQL.query per key-set group, so atomicity depends
on Ash wrapping the batch in a transaction: on the default transaction: :batch
path (this layer advertises can?(:transact)), a later-group failure rolls back
earlier groups; under transaction: false the groups run unwrapped and a partial
write is possible — the same contract single-create and AshPostgres carry.