Skip to content

Commit d6e33d2

Browse files
authored
docs: change project status to stable (#88)
1 parent 5bedf8a commit d6e33d2

File tree

1 file changed

+105
-22
lines changed

1 file changed

+105
-22
lines changed

README.md

Lines changed: 105 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -44,22 +44,35 @@ And please give some love to our featured sponsors 🤩:
4444

4545
## Status
4646

47-
**EXPERIMENTAL**
48-
49-
Tests are in place for many of the APIs, though the API remains undocumented
50-
(deliberately) and thus if you use the API directly (as opposed to using the
51-
CLI) you should expect to have to update your code from time to time. (We advise
52-
using TypeScript to make spotting breaking changes easier.) There are no
53-
automated integration tests of the CLI yet (although mostly all it does is hand
54-
off to the API).
55-
56-
There are people (including the maintainer) using this software to manage
57-
production databases. It is also used in
58-
[Graphile Starter](https://github.com/graphile/starter). However, it is not for
59-
the faint of heart - this software is powerful and requires knowledge of SQL. If
60-
you don't understand what makes Graphile Migrate awesome, or you're concerned
61-
about it continuing to evolve, you may want to consider an alternative migration
62-
framework such as these awesome (and quite diverse) projects:
47+
**STABLE**
48+
49+
This project is intended to be consumed via the CLI, which is stable and is
50+
being used in production in many projects. The CLI doesn't have explicit tests
51+
(PR welcome!), but it's a thin wrapper around the programmatic API which has
52+
copious tests.
53+
54+
The programmatic API is deliberately undocumented; it is not a public interface
55+
at this time (though it is fully typed in TypeScript). We reserve the right to
56+
make breaking changes to the programmatic API in patch releases (though this has
57+
not happened yet and is unlikely to happen without good reason). Should you need
58+
to use the programmatic API, please get in touch to encourage us to make this a
59+
supported interface ─ we'd love to know how you're using it!
60+
61+
The project as a whole is stable, but the approach is still "experimental", in
62+
particular:
63+
64+
- because committed migrations are hashed you cannot edit old migrations; this
65+
may cause you issues should you upgrade PostgreSQL and it drops support for a
66+
syntax or feature you were previously using. We plan to fix this issue _if and
67+
when_ it occurs, so if this affects you please open a detailed issue.
68+
- the approach of up-only and re-runnable migrations is not for the faint of
69+
heart ─ it requires solid SQL knowledge and if insufficient attention is paid
70+
it could result in your migrations and your local database state drifting
71+
apart (see 'Drift' below).
72+
73+
If you don't understand what makes Graphile Migrate awesome, you may want to
74+
consider an alternative migration framework such as these awesome (and quite
75+
diverse) projects:
6376

6477
- [db-migrate](https://db-migrate.readthedocs.io/en/latest/Getting%20Started/commands/)
6578
- [sqitch](https://sqitch.org/)
@@ -130,13 +143,13 @@ PostgreSQL servers have a default database called `postgres` which is a good
130143
choice for this).
131144

132145
> Your database URL is needed for most Graphile Migrate commands. The shadow
133-
> database URL is needed for the development-only commands `commit`,
134-
> `uncommit` and `reset`. The root database URL is needed to drop and
135-
> recreate databases, i.e. for the `reset` command and for commands that call
136-
> it (`commit` and `uncommit`, which reset the shadow database).
146+
> database URL is needed for the development-only commands `commit`, `uncommit`
147+
> and `reset`. The root database URL is needed to drop and recreate databases,
148+
> i.e. for the `reset` command and for commands that call it (`commit` and
149+
> `uncommit`, which reset the shadow database).
137150
>
138-
> **NOTE**: you should not need the shadow database URL or root database URL
139-
> in production (you only need the `graphile-migrate migrate` command in
151+
> **NOTE**: you should not need the shadow database URL or root database URL in
152+
> production (you only need the `graphile-migrate migrate` command in
140153
> production) unless you have actions that need them.
141154
142155
```bash
@@ -730,6 +743,76 @@ Since "superuser" has a specific meaning and is not strictly required for these
730743
activities we avoid that term, however you may find that you use a superuser as
731744
your root user - this is expected.
732745
746+
## Drift
747+
748+
> **NOTE**: drift only affects your local development database, it cannot occur
749+
> in your production database assuming you're only using
750+
> `graphile-migrate migrate` in production.
751+
752+
In development, if you're insufficiently careful with modifications to
753+
`current.sql` (including when you choose to save the file, and when switching
754+
branches in `git`) you may end up with a local database state that differs from
755+
what you'd expect given the committed migrations and contents of `current.sql`.
756+
We **strongly recommend against auto-save** for this reason; and recommend that
757+
you keep a dumped `schema.sql` to help you spot unexpected changes.
758+
759+
Here's an illustrative example to explain the drift phenomenon, with function
760+
inspired by [XKCD221](https://xkcd.com/221/). Imagine that you're running
761+
`graphile-migrate watch` locally and you write the following to `current.sql`:
762+
763+
```sql
764+
-- Revision 1
765+
create function rnd() returns int as $$
766+
select 4;
767+
$$ language sql stable;
768+
```
769+
770+
Because `watch` runs the contents of `current.sql` whenever it changes, this
771+
will create the `rnd()` function in your local database.
772+
773+
A couple seconds later you change your mind, and decide to rename the function,
774+
writing the following to `current.sql`:
775+
776+
```sql
777+
-- Revision 2
778+
create function get_random_number() returns int as $$
779+
select 4;
780+
$$ language sql stable;
781+
```
782+
783+
This creates `get_random_number()`, but no-one ever said to delete `rnd()`, so
784+
now both functions exist. According to the committed migrations and
785+
`current.sql` only `get_random_number()` should exist. The existence of the
786+
orphaned `rnd()` function in your local database is what we term "drift" ─ this
787+
function will never appear in your production database even after you commit
788+
this latest migration; it also won't be in your shadow database (because we
789+
reset the shadow database and reapply all the migrations frequently).
790+
791+
Since Graphile Migrate doesn't know how to reverse the SQL you've written, it's
792+
up to you to make the SQL safe so that it can be ran over and over, and adjust
793+
to your changes. The two to `current.sql` versions above should have been
794+
795+
```sql
796+
-- Revision 1
797+
drop function if exists rnd();
798+
799+
create function rnd() returns int as $$
800+
select 4;
801+
$$ language sql stable;
802+
```
803+
804+
and
805+
806+
```sql
807+
-- Revision 2
808+
drop function if exists rnd();
809+
drop function if exists get_random_number();
810+
811+
create function get_random_number() returns int as $$
812+
select 4;
813+
$$ language sql stable;
814+
```
815+
733816
## TODO:
734817
735818
- [ ] Store pgSettings with committed transactions to protect against user edits

0 commit comments

Comments
 (0)