Postmodern Passenger Pigeon
Postmodern passenger pigeon is a migration manager for postmodern. It’s similar to alembic for sqlalchemy. It’s probably much dumber, though.
To set up a project to use ppp, make sure you define a
pigeon.toml file in the root of the project. Ppp will look for that file to find out where you want to store your migrations.
PPP uses a table in your database called
pigeon_revision to keep track of what migration you’re on. If something goes wrong and you have to fix a migration manually, you can make sure PPP thinks a migration has been run by inserting the migration’s id (timestamp) into this table.
pigeon.toml file mostly exists to tell ppp where to find your migration definitions (
migration-directory). You can optionally tell it how to connect to the database here (
database-url) but it will look at the
DATABASE_URL environment variable if the database url isn’t defined in the config file. The latter is likely how you will use it in a hosted situation.
pigeon.toml might look like this:
migration-directory = "revisions/" database-url = "postgres://postgres@localhost/postgres"
new-migration function will create a new migration definition in the path specified in your configuration file. Files are named by a revision id, which is actually the universal time, followed by any arbitrary string. PPP will kebab your migration name for the purpose of creating the name, so, for example
Create People Table might be named something like
After creating a few migrations, the
revisions/ directory might look like this:
3727984190-create-people-table.lisp 3727989266-create-pet-table.lisp 3727998187-create-favorite-foods-table.lisp 3728002236-set-all-the-villagers-on-fire.lisp
An individual migration will look something like this:
"Creates the people table." (defun up () (query (:create-table people ((id :type integer :primary-key t) (name :type (string 20)))))) (defun down () (query (:drop-table 'people)))
A migration file starts with an optional docstring and then defines
up is responsible for migrating the database forward.
down is responsible for reversing the changes made by
up. This is essentially the same scheme used by alembic or activerecord.
Migrations are lisp code files, and will be evaluated in their own package that’s created for them and then destroyed after they run. The package uses everything from
common-lisp and the
ppp.operations package, which reexports a few postmodern functions useful for migrations. It’s best not to assume anything else is loaded at migration run time unless you specifically design your migrations workflow around that assumption.