A PostgreSQL adapter for the lightweight database migration system Schemamama. Depends on the postgres
crate.
If you're using Cargo, just add Schemamama to your Cargo.toml
:
[dependencies]
schemamama = "0.3"
schemamama_postgres = "0.3"
postgres = "0.17"
First, define some migrations:
#[macro_use]
extern crate schemamama;
extern crate schemamama_postgres;
extern crate postgres;
use postgres::{Client, Transaction, error::Error as PostgresError, NoTls};
use schemamama::{Migration, Migrator};
use schemamama_postgres::{PostgresAdapter, PostgresMigration};
struct CreateUsers;
// Instead of using sequential numbers (1, 2, 3...), you may choose to use a collaborative
// versioning scheme, such as epoch timestamps.
migration!(CreateUsers, 1, "create users table");
impl PostgresMigration for CreateUsers {
fn up(&self, transaction: &mut Transaction) -> Result<(), PostgresError> {
transaction.execute("CREATE TABLE users (id BIGINT PRIMARY KEY);", &[]).map(|_| ())
}
fn down(&self, transaction: &mut Transaction) -> Result<(), PostgresError> {
transaction.execute("DROP TABLE users;", &[]).map(|_| ())
}
}
struct CreateProducts;
migration!(CreateProducts, 2, "create products table");
impl PostgresMigration for CreateProducts {
// ...
}
Then, run the migrations!
let url = "postgres://postgres@localhost";
let client = Client::connect(url, NoTls).unwrap();
let adapter = PostgresAdapter::new(&mut client);
// Create the metadata tables necessary for tracking migrations. This is safe to call more than
// once (`CREATE TABLE IF NOT EXISTS schemamama` is used internally):
adapter.setup_schema().unwrap();
let mut migrator = Migrator::new(adapter);
migrator.register(Box::new(CreateUsers));
migrator.register(Box::new(CreateProducts));
// Execute migrations all the way upwards:
migrator.up(None);
assert_eq!(migrator.current_version(), Some(2));
// Reverse all migrations:
migrator.down(None);
assert_eq!(migrator.current_version(), None);
To run cargo test
, you must have PostgreSQL running locally with a user role named postgres
with login access to a database named postgres
. All tests will work in the pg_temp
schema, so the database will not be modified.