Multi-Database
Map tables across named databases while preserving routing and cache isolation.
Database map
Configure multiple databases when a graph spans operational, analytics, or source-specific stores.
databases:
primary:
type: postgres
url: ${PRIMARY_DATABASE_URL}
analytics:
type: snowflake
url: ${ANALYTICS_DATABASE_URL}Tables can be assigned in the database config or on individual table entries.
tables:
- name: users
schema: public
database: primary
- name: audit_logs
schema: main
database: local
- name: events
database: mongodb
columns:
- name: user_id
foreign_key: users.idExample_multiDBTableMapping
tests/multidb_test.go:205Root-level multi-database queries
Independent root fields can be grouped by database, executed against the correct compiler and connection pool, then merged into one JSON object.
query Dashboard {
users(limit: 1, order_by: { id: asc }) {
id
full_name
}
audit_logs(limit: 1, order_by: { id: asc }) {
id
action
}
events(limit: 1, order_by: { id: asc }) {
id
type
}
}Duplicate root keys across database results fail instead of silently overwriting data.
Example_multiDBQueryPostgres
tests/multidb_test.go:39Example_multiDBQuerySQLite
tests/multidb_test.go:74Example_multiDBQueryMongoDB
tests/multidb_test.go:107TestMergeRootResults
core/multidb_test.go:273Nested database joins
GraphJin can reason about tables from multiple configured databases and keep query/cache identity scoped by database.
When a nested relationship crosses a database boundary, GraphJin does not attempt to emit one impossible SQL statement. It:
- fetches the parent rows,
- extracts the parent join key from the JSON result,
- builds a child GraphQL query filtered by the foreign key,
- compiles and executes that child query with the target database’s compiler,
- replaces the placeholder field in the parent JSON.
query {
users(limit: 5, order_by: { id: asc }) {
id
full_name
events {
id
type
}
}
}The exact availability of a nested cross-database path depends on discovered or configured relationship metadata.
TestBuildChildGraphQLQueryNestedDatabaseJoin
core/multidb_test.go:809TestResolveDatabaseJoinsNullID
core/multidb_test.go:1045Cache isolation and compiler isolation
Each database context has its own type, schema, QCode compiler, SQL/DSL compiler, and connection pool. Query cache keys include the database identity so the same operation name cannot accidentally reuse SQL from another dialect.
Example_multiDBCacheKeyIsolation
tests/multidb_test.go:141TestCacheKeyIncludesDatabase
core/multidb_test.go:14Operational advice
Use explicit database names when the same table name exists in more than one source. Ambiguous unqualified lookups should fail early so query authors fix the source reference.
TestGetTableSchema_AmbiguousAcrossDatabases
core/api_multidb_test.go:12What to document in reviews
For multi-database changes, describe:
- which source owns each table-like root,
- whether the query is root-level composition or nested database join,
- whether a relationship is same-source, remote API, MongoDB lookup, or database join,
- which features are expected to be portable across the selected dialects,
- and how cache invalidation should identify source-owned row references.