2020-01-14 15:57:45 +03:00
|
|
|
.. meta::
|
|
|
|
:description: Manage migrations on an existing database and Hasura instance
|
|
|
|
:keywords: hasura, docs, migration, existing database
|
|
|
|
|
2020-04-29 11:00:26 +03:00
|
|
|
.. _manage_migrations_v1:
|
2020-03-11 22:42:36 +03:00
|
|
|
|
2020-04-29 11:00:26 +03:00
|
|
|
Managing Postgres schema migrations and metadata (config v1)
|
|
|
|
============================================================
|
2019-03-28 13:51:58 +03:00
|
|
|
|
|
|
|
.. contents:: Table of contents
|
|
|
|
:backlinks: none
|
|
|
|
:depth: 1
|
|
|
|
:local:
|
|
|
|
|
2020-04-29 11:00:26 +03:00
|
|
|
Introduction
|
|
|
|
------------
|
2019-03-28 13:51:58 +03:00
|
|
|
|
2020-04-29 11:00:26 +03:00
|
|
|
If you don't already use any tool to manage your Postgres schema, you can use
|
|
|
|
Hasura to do that for you. Hasura has a CLI which will help you save each
|
|
|
|
action that you do on the console, including creating tables/views and schema
|
|
|
|
modifying SQL statements, as YAML files. These files are called migrations and
|
|
|
|
they can be applied and rolled back step-by-step. These files can be version
|
|
|
|
controlled and can be used with your CI/CD system to make incremental updates.
|
|
|
|
|
2020-06-11 13:14:04 +03:00
|
|
|
Let's say we have the following two tables in our schema:
|
|
|
|
|
|
|
|
.. code-block:: sql
|
|
|
|
|
|
|
|
author (id uuid, name text, rating integer)
|
|
|
|
article (id uuid, title text, content text, author_id uuid)
|
|
|
|
|
|
|
|
Now we want to set up migrations starting with this schema.
|
|
|
|
|
2020-07-15 00:30:35 +03:00
|
|
|
Before you begin
|
|
|
|
----------------
|
2019-03-28 13:51:58 +03:00
|
|
|
|
2019-09-11 10:17:14 +03:00
|
|
|
To use migrations effectively, the console on the server (which is served at
|
2019-03-28 13:51:58 +03:00
|
|
|
``/console``) should be disabled and all changes must go through the console
|
2020-04-29 11:00:26 +03:00
|
|
|
served by the CLI. Otherwise, changes could be made through the server console
|
|
|
|
and they will not be tracked by migrations.
|
2019-03-28 13:51:58 +03:00
|
|
|
|
2019-09-11 10:17:14 +03:00
|
|
|
So, the first step is to disable the console served by the GraphQL engine server. In
|
|
|
|
order to do that, remove the ``--enable-console`` flag from the command that starts
|
2019-03-28 13:51:58 +03:00
|
|
|
the server or set the following environment variable to false:
|
|
|
|
|
|
|
|
.. code-block:: bash
|
|
|
|
|
|
|
|
HASURA_GRAPHQL_ENABLE_CONSOLE=false
|
|
|
|
|
|
|
|
.. note::
|
|
|
|
|
|
|
|
If this is set in YAML, make sure you quote the word false, i.e.
|
|
|
|
``HASURA_GRAPHQL_ENABLE_CONSOLE: "false"``.
|
|
|
|
|
|
|
|
Step 1: Install the Hasura CLI
|
|
|
|
------------------------------
|
|
|
|
|
|
|
|
Follow the instructions in :ref:`install_hasura_cli`.
|
|
|
|
|
|
|
|
Step 2: Set up a project directory
|
|
|
|
----------------------------------
|
|
|
|
|
2020-06-11 13:14:04 +03:00
|
|
|
For the endpoint referred here, let's say you've
|
2019-03-28 13:51:58 +03:00
|
|
|
deployed the GraphQL engine on Heroku, then this endpoint is:
|
2020-06-11 13:14:04 +03:00
|
|
|
``https://my-graphql.herokuapp.com``. In case you've deployed Hasura using Docker,
|
|
|
|
the URL might be ``http://xx.xx.xx.xx:8080``. This endpoint should **not** contain
|
2019-05-10 09:05:11 +03:00
|
|
|
the ``v1/graphql`` API path. It should just be the hostname and any
|
2019-03-28 13:51:58 +03:00
|
|
|
sub-path if it is configured that way.
|
|
|
|
|
2020-06-11 13:14:04 +03:00
|
|
|
Let's set up a project directory by executing the following command:
|
|
|
|
|
2019-03-28 13:51:58 +03:00
|
|
|
.. code-block:: bash
|
|
|
|
|
2020-07-08 16:04:24 +03:00
|
|
|
hasura init my-project --endpoint http://my-graphql.herokuapp.com
|
2019-03-28 13:51:58 +03:00
|
|
|
|
|
|
|
cd my-project
|
|
|
|
|
|
|
|
This will create a new directory called ``my-project`` with a ``config.yaml``
|
2019-09-11 10:17:14 +03:00
|
|
|
file and a ``migrations`` directory. This directory structure is mandatory to use
|
2020-06-11 13:14:04 +03:00
|
|
|
Hasura migrations.
|
|
|
|
|
|
|
|
These directories can be committed to version control.
|
2019-03-28 13:51:58 +03:00
|
|
|
|
|
|
|
.. note::
|
|
|
|
|
|
|
|
In case there is an admin secret set, you can set it as an environment
|
2019-08-09 12:23:38 +03:00
|
|
|
variable ``HASURA_GRAPHQL_ADMIN_SECRET=<your-admin-secret>`` on the local
|
2019-09-11 10:17:14 +03:00
|
|
|
machine and the CLI will use it. You can also use it as a flag to CLI:
|
2019-08-09 12:23:38 +03:00
|
|
|
``--admin-secret '<your-admin-secret>'``.
|
2019-03-28 13:51:58 +03:00
|
|
|
|
2020-04-29 11:00:26 +03:00
|
|
|
Step 3: Initialize the migrations (optional)
|
|
|
|
--------------------------------------------
|
|
|
|
|
2020-06-11 13:14:04 +03:00
|
|
|
If you have previously set up your database, you need to initialize your
|
2020-04-29 11:00:26 +03:00
|
|
|
migrations with the current state of the database.
|
2019-03-28 13:51:58 +03:00
|
|
|
|
2019-04-30 11:34:08 +03:00
|
|
|
Create a migration called ``init`` by exporting the current Postgres schema and
|
2019-09-11 10:17:14 +03:00
|
|
|
metadata from the server:
|
2019-03-28 13:51:58 +03:00
|
|
|
|
2019-04-30 11:34:08 +03:00
|
|
|
.. code-block:: bash
|
2019-03-28 13:51:58 +03:00
|
|
|
|
2019-05-20 12:42:36 +03:00
|
|
|
# (available after version v1.0.0-alpha45)
|
2020-06-11 13:14:04 +03:00
|
|
|
# create migration files (note that this will only export the public schema from postgres)
|
2019-04-30 11:34:08 +03:00
|
|
|
hasura migrate create "init" --from-server
|
2019-03-28 13:51:58 +03:00
|
|
|
|
2019-04-30 11:34:08 +03:00
|
|
|
# note down the version
|
2020-06-11 13:14:04 +03:00
|
|
|
|
2019-04-30 11:34:08 +03:00
|
|
|
# mark the migration as applied on this server
|
|
|
|
hasura migrate apply --version "<version>" --skip-execution
|
2019-03-28 13:51:58 +03:00
|
|
|
|
2019-05-16 09:19:22 +03:00
|
|
|
|
2020-06-11 13:14:04 +03:00
|
|
|
This command will create a new migration under the ``migrations`` directory
|
2019-04-30 11:34:08 +03:00
|
|
|
with the file name as ``<timestamp(version)>_init.up.yaml``. This file will
|
|
|
|
contain the required information to reproduce the current state of the server
|
2020-06-11 13:14:04 +03:00
|
|
|
including the Postgres (public) schema and Hasura metadata. If you'd like to read more
|
2020-04-29 11:00:26 +03:00
|
|
|
about the format of migration files, check out the :ref:`migration_file_format_v1`.
|
2019-03-28 13:51:58 +03:00
|
|
|
|
2020-06-11 13:14:04 +03:00
|
|
|
The apply command will mark this migration as "applied" on the server.
|
|
|
|
|
|
|
|
.. note::
|
|
|
|
|
|
|
|
From version ``v1.0.0`` and higher, a directory is created for each migration with the name format ``timestamp_name``.
|
|
|
|
The directory contains four files: ``up.sql``, ``up.yaml``, ``down.sql`` and ``down.yaml``.
|
|
|
|
|
2019-03-28 13:51:58 +03:00
|
|
|
.. note::
|
|
|
|
|
2019-06-27 14:34:19 +03:00
|
|
|
If you need to export other schemas along with ``public``, you can name them using the
|
|
|
|
``--schema`` flag.
|
|
|
|
|
|
|
|
For example, to export schemas ``public``, ``schema1`` and ``schema2``,
|
|
|
|
execute the following command:
|
|
|
|
|
|
|
|
.. code-block:: bash
|
|
|
|
|
|
|
|
hasura migrate create "init" --from-server --schema "public" --schema "schema1" --schema "schema2"
|
2019-03-28 13:51:58 +03:00
|
|
|
|
|
|
|
Step 4: Use the console from the CLI
|
|
|
|
------------------------------------
|
|
|
|
|
|
|
|
From this point onwards, instead of using the console at
|
2019-09-11 10:17:14 +03:00
|
|
|
``http://my-graphql.herokuapp.com/console`` you should use the console from the CLI
|
2019-03-28 13:51:58 +03:00
|
|
|
by running:
|
|
|
|
|
|
|
|
.. code-block:: bash
|
|
|
|
|
|
|
|
# in project dir
|
|
|
|
hasura console
|
|
|
|
|
|
|
|
Step 5: Add a new table and see how a migration is added
|
|
|
|
--------------------------------------------------------
|
|
|
|
|
2020-04-29 11:00:26 +03:00
|
|
|
As you use the Hasura console UI to make changes to your schema, migration files
|
|
|
|
are automatically generated in the ``migrations/`` directory in your project.
|
2019-03-28 13:51:58 +03:00
|
|
|
|
2020-06-11 13:14:04 +03:00
|
|
|
Let's add the following table to our schema:
|
|
|
|
|
|
|
|
.. code-block:: sql
|
|
|
|
|
|
|
|
address (id uuid, street text, zip text, city text, country text)
|
|
|
|
|
|
|
|
In the migrations directory, you should now see a new migration created for the above statement.
|
|
|
|
|
2019-03-28 13:51:58 +03:00
|
|
|
.. note::
|
|
|
|
|
|
|
|
Migrations are only created when using the console through CLI.
|
|
|
|
|
2019-09-11 10:17:14 +03:00
|
|
|
Step 6: Apply the migrations on another instance of the GraphQL engine
|
|
|
|
----------------------------------------------------------------------
|
2019-03-28 13:51:58 +03:00
|
|
|
|
|
|
|
Apply all migrations present in the ``migrations/`` directory on a new
|
|
|
|
instance at ``http://another-graphql-instance.herokuapp.com``:
|
|
|
|
|
|
|
|
.. code-block:: bash
|
|
|
|
|
|
|
|
# in project dir
|
|
|
|
hasura migrate apply --endpoint http://another-graphql-instance.herokuapp.com
|
|
|
|
|
|
|
|
In case you need an automated way of applying the migrations, take a look at the
|
2020-04-29 11:00:26 +03:00
|
|
|
:ref:`CLI-Migrations <auto_apply_migrations_v1>` Docker image, which can start the
|
2019-09-11 10:17:14 +03:00
|
|
|
GraphQL engine after automatically applying the migrations which are
|
2020-04-29 11:00:26 +03:00
|
|
|
mounted into a directory.
|
2019-03-28 13:51:58 +03:00
|
|
|
|
2020-06-11 13:14:04 +03:00
|
|
|
If you now open the console of the new instance, you can see that the three tables have been created and are tracked:
|
|
|
|
|
|
|
|
.. thumbnail:: /img/graphql/manual/migrations/tracked-tables.png
|
|
|
|
:alt: Tracked tables from Hasura migrations
|
|
|
|
:width: 30%
|
|
|
|
|
2019-09-11 10:17:14 +03:00
|
|
|
Step 7: Check the status of migrations
|
|
|
|
--------------------------------------
|
2019-03-28 13:51:58 +03:00
|
|
|
|
|
|
|
.. code-block:: bash
|
|
|
|
|
|
|
|
# in project dir
|
|
|
|
hasura migrate status
|
|
|
|
|
|
|
|
This command will print out each migration version present in the ``migrations``
|
|
|
|
directory and the ones applied on the database, along with a status text.
|
|
|
|
|
|
|
|
For example,
|
|
|
|
|
|
|
|
.. code-block:: bash
|
|
|
|
|
|
|
|
$ hasura migrate status
|
|
|
|
VERSION SOURCE STATUS DATABASE STATUS
|
|
|
|
1550925483858 Present Present
|
|
|
|
1550931962927 Present Present
|
|
|
|
1550931970826 Present Present
|
|
|
|
|
2019-09-11 10:17:14 +03:00
|
|
|
Such a migration status indicates that there are 3 migration versions in the
|
2019-03-28 13:51:58 +03:00
|
|
|
local directory and all of them are applied on the database.
|
|
|
|
|
|
|
|
If ``SOURCE STATUS`` indicates ``Not Present``, it means that the migration
|
|
|
|
version is present on the server, but not on the current user's local directory.
|
|
|
|
This typically happens if multiple people are collaborating on a project and one
|
2019-09-11 10:17:14 +03:00
|
|
|
of the collaborators forgot to pull the latest changes which included the latest
|
2019-03-28 13:51:58 +03:00
|
|
|
migration files or another collaborator forgot to push the latest migration
|
|
|
|
files that were applied on the database. Syncing of the files would fix the
|
|
|
|
issue.
|
|
|
|
|
|
|
|
If ``DATABASE STATUS`` indicates ``Not Present``, it denotes that there are new
|
|
|
|
migration versions in the local directory which are not applied on the database
|
2020-06-11 13:14:04 +03:00
|
|
|
yet. Executing a ``migrate apply`` will resolve this.
|