Check out v4 of the Fauna CLI
v4 of the Fauna CLI is now in beta. The new version introduces enhancements to the developer experience, including an improved authentication workflow. To get started, check out the CLI v4 quick start. |
Manage schema as .fsl
files using the Fauna CLI
A schema controls a database’s structure and behavior. In Fauna, you define schema the using Fauna Schema Language (FSL).
You can manage schemas as .fsl
files using the
Fauna CLI.
This page covers how to manage .fsl
files using the CLI. Using .fsl
files
lets you version control, review, and automate schema changes.
To manage |
Set up a schema directory
You typically store .fsl
files in a schema directory alongside your
application code. The directory can use any name. schema
is a common choice.
For more information about setting up a project using the CLI, see Set up a project using FSL and the Fauna CLI.
Create FSL schema files
An .fsl
file can contain schema for multiple resources. You can use multiple
.fsl
files to organize your schema. While subject to limits, there
is no performance benefit to splitting .fsl
files or storing larger,
individual files.
Valid FSL filenames must use the .fsl
extension and can’t start with *
.
FSL schema syntax
The following table links to FSL syntax to use when creating .fsl
files:
Resource | FSL Syntax |
---|---|
Collections, including:
|
|
Common conventions
A common convention is to organize your .fsl
files by resource type to
maintain a clear and maintainable schema structure:
schema/
├── collections.fsl # Collection schema
├── functions.fsl # User-defined functions
├── roles.fsl # Role definitions
└── access-providers.fsl # Access provider definitions
When you push .fsl
files to Fauna, Fauna retains the filenames and directory
organization. This lets you later pull the same files.
Filenames for generated FSL schema
Schema created using FQL schema methods or the
Fauna Dashboard are stored in the main.fsl
file. After pulling the file locally, you can reorganize the schema into
separate files as desired.
Push schema to Fauna
A project directory includes .fsl
files for the project’s database. You can
use the Fauna CLI to push a project’s .fsl
files to Fauna.
Run a staged schema change
A staged schema change lets you change one or more collection schema without index downtime due to index builds.
To run a staged schema change, you must use the Fauna CLI or the Fauna Core HTTP API’s Schema endpoints.
You can’t run a staged schema change using FQL schema methods or the Fauna Dashboard.
To run a staged schema change using the Fauna CLI:
-
Make the desired changes to
.fsl
files in your schema directory.You can’t use a staged schema change to delete or rename schema. Instead, delete or rename the schema in a separate unstaged schema change.
-
Use
fauna schema push
to stage the schema changes.fauna schema push
stages schema changes by default:# Replace 'us' with your preferred Region Group: # 'us' (United States), 'eu' (Europe), or `global`. # Replace 'my_db' with your database's name. fauna schema push \ --database us/my_db \ --dir /path/to/schema/dir
A database can have one staged schema change at a time. You can update staged schema using
fauna schema push
.When a database has staged schema, any access or updates done using FQL’s schema commands on related system collections interact with the staged schema, not the database’s active schema.
For example, when schema changes are staged,
Collection.all()
returnsCollection
documents for the staged collection schema, not the database’sCollection
documents.If a database has staged schema, you can’t edit the database’s active schema using FQL, the Dashboard, or an unstaged schema change. You must first abandon the staged schema change.
-
Use
fauna schema status
to check the status of the staged schema:fauna schema status \ --database us/my_db
Possible statuses:
Staged status Description pending
Changes are being processed. New indexes are still being built.
ready
All indexes have been built. Changes are ready to commit.
failed
There was an error during the staging process.
-
When the status is
ready
, usefauna schema commit
to apply the staged schema to the database:fauna schema commit \ --database us/my_db
You can only commit staged schema with a status of
ready
.If you no longer wish to apply the staged schema or if the status is
failed
, usefauna schema abandon
to unstage the schema:fauna schema abandon \ --database us/my_db
Run an unstaged schema change
To immediately commit schema changes without staging, use the --active
option:
fauna schema push \
--database us/my_db \
--active
Schema changes that trigger an index build may result in downtime where the index is not queryable.
You can’t run an unstaged schema change if a database has staged schema. You must abandon the staged schema changes first.
Create and delete schema
Committing a schema to Fauna creates the related resource. For example, committing a collection schema to Fauna creates the collection.
Similarly, you can delete the resource by removing the schema from the FSL files in a project’s schema directory then pushing the changes to Fauna.
Compare local, staged, and active schema
Use fauna schema diff
to compare a project’s
local, staged, and active schema.
For example, to compare the local schema to the remote staged schema:
fauna schema diff \
--database us/my_db
If there is no staged schema, |
To compare the local schema to the remote active schema:
fauna schema diff \
--database us/my_db \
--active
To compare the remote active schema to the remote staged schema:
fauna schema diff \
--database us/my_db \
--staged
By default, fauna schema diff
prints a semantic
summary of the changes. To get a textual diff, use the --text
option. For
example:
fauna schema diff \
--database us/my_db \
--text
Pull remote schema from Fauna
Use fauna schema pull
to pull a database’s
remote .fsl
schema files into a project’s local schema directory:
fauna schema pull \
--database us/my_db
If the database has staged schema, the command pulls the database’s remote staged schema by default.
If the database has no staged schema, the command pulls the database’s remote active schema.
Pull active schema files
Use the fauna schema pull
command’s --active
option to pull the database’s remote active schema regardless of whether the
database has staged schema:
fauna schema pull \
--database us/my_db \
--active
Delete local files
The fauna schema pull
command overwrites
existing schema files in the local directory.
If wanted, you can use the --delete
option to delete local .fsl
files that
aren’t part of the remote schema:
fauna schema pull \
--database us/my_db \
--delete
Manage schema with a CI/CD pipeline
You can use schema-related Fauna CLI commands to manage schema as .fsl
files.
The following examples show how you can stage and commit schema
changes using a CI/CD pipeline:
You can’t use a staged schema change to delete or rename schema. Instead, delete or rename the schema in a separate unstaged schema change. |
GitHub
In your project, create a .github/workflows/main.yml
file with the following
contents:
name: Main CI
on:
push:
branches: [ main ]
jobs:
ci:
runs-on: ubuntu-latest
env:
FAUNA_SECRET: ${{ secrets.FAUNA_SECRET }}
strategy:
matrix:
node-version: [20.x]
steps:
- uses: actions/checkout@v3
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
- name: Install Fauna CLI
run: npm install -g fauna-shell@">=4.0.0-beta"
- name: Stage schema
run: fauna schema push --secret $FAUNA_SECRET --no-input --dir ./path/to/schema/dir
- name: Check schema status
id: schema-check
run: |
attempts=0
max_attempts=60 # 30 minutes with 30-second intervals
while [ $attempts -lt $max_attempts ]; do
STATUS=$(fauna schema status --secret $FAUNA_SECRET | grep -oP '(?<=Staged changes: )\w+')
echo "Current status: $STATUS"
if [ "$STATUS" = "ready" ]; then
echo "Schema is ready"
echo "schema_status=ready" >> $GITHUB_OUTPUT
exit 0
elif [ "$STATUS" = "failed" ]; then
echo "Schema staging failed"
echo "schema_status=failed" >> $GITHUB_OUTPUT
exit 1
fi
echo "Waiting for schema to be ready..."
sleep 30
attempts=$((attempts + 1))
done
echo "Timeout waiting for schema status"
echo "schema_status=timeout" >> $GITHUB_OUTPUT
exit 1
- name: Commit or abandon schema
if: always()
run: |
if [[ "${{ steps.schema-check.outputs.schema_status }}" == "ready" ]]; then
fauna schema commit --secret $FAUNA_SECRET --no-input
else
fauna schema abandon --secret $FAUNA_SECRET --no-input
fi
GitLab
In your project, create a .gitlab-ci.yml
file with the following
contents:
stages:
- stage_schema
- commit_or_abandon_schema
variables:
FAUNA_SECRET: $FAUNA_SECRET
default:
image: node:20
stage_schema:
stage: stage_schema
script:
- npm install -g fauna-shell@">=4.0.0-beta"
- fauna schema push --secret $FAUNA_SECRET --no-input --dir ./path/to-schema/dir
- |
attempts=0
max_attempts=60
while [ $attempts -lt $max_attempts ]; do
STATUS=$(fauna schema status --secret $FAUNA_SECRET | grep -oP '(?<=Staged changes: )\w+')
echo "Current status: $STATUS"
if [ "$STATUS" = "ready" ]; then
echo "Schema is ready"
exit 0
elif [ "$STATUS" = "failed" ]; then
echo "Schema staging failed"
exit 1
fi
echo "Waiting for schema to be ready..."
sleep 30
attempts=$((attempts + 1))
done
echo "Timeout waiting for schema status"
exit 1
only:
- main
commit_or_abandon_schema:
stage: commit_or_abandon_schema
script:
- npm install -g fauna-shell@">=4.0.0-beta"
- |
if [ $? -eq 0 ]; then
fauna schema commit --secret $FAUNA_SECRET --no-input
else
fauna schema abandon --secret $FAUNA_SECRET --no-input
exit 1
fi
only:
- main
Manage schema for child databases
Fauna databases support a hierarchical database structure with top-level and child databases. You can manage schema for child databases using:
scoped keys with the CLI or using FQL schema methods.
Use scoped keys with the CLI
The Fauna CLI’s fauna schema
commands let you
specify a --database
when you use
interactive login or an
account key for authentication. You
can use --database
to interact with any child database the related account key
has access to.
# Stage schema changes for the
# 'us/parent_db/child_db' database.
fauna schema push \
--database us/parent_db/child_db \
--dir /path/to/schema/dir
Alternatively, you can use --secret
to provide a
scoped key. A scoped key lets you
interact with a child database’s schema using a parent database’s admin key.
For example, with a parent database’s admin key secret, you can access a child database by appending the child database name and role:
# Use a scoped key from a parent database
# to stage schema in the 'child_db' child database.
# The scoped key has `admin` privileges.
fauna schema push \
--secret fn123:child_db:admin \
--dir /path/to/schema/dir
Use FQL schema methods
Fauna stores each schema for a database as an FQL document in a related system collection.
You can use methods for these system collections to programmatically manage the schema of child databases using FQL queries. Use a scoped key to manage a child database’s schema using queries in a parent database.
FSL schema | FQL system collection |
---|---|
Use Schema HTTP API endpoints
You can use the Fauna Core HTTP API’s Schema endpoints to perform programmatically perform schema changes, including staged schema changes. Use a scoped key to manage a child database’s schema using a parent database’s key secret.
For example, the following
Update schema
files request uses a scoped key that impersonates a key with the admin
role
for the childDb
child database. The request starts a staged schema change
for the childDb
child database:
curl -X POST "https://db.fauna.com/schema/1/update?staged=true" \
-H "Authorization: Bearer <FAUNA_SECRET>:childDb:admin" \
-H "Content-Type: multipart/form-data" \
-F "collections.fsl=@./schema/collections.fsl" \
-F "functions.fsl=@./schema/functions.fsl"
Is this article helpful?
Tell Fauna how the article can be improved:
Visit Fauna's forums
or email docs@fauna.com
Thank you for your feedback!