Export to GitHub

tesla-pylons-elixir - Migrations.wiki


Introduction

Tesla is integrated with the migrate library for SQLAlchemy. This means you can run migrations through paster commands. In addition, much of the spadework in using migrate, such as creating a repository, is done for you. This document is a guide to using migrate with Tesla; refer to the migrate documentation for more details.

Caveats

  1. According to some reports, some migrate functions do not work with the latest version of SQLAlchemy.

  2. A number of migrate functions, for example DROP COLUMN, are not available for SQLite.

If you run into these or other related issues, then refer to the documentation, mailing lists and other sources for SQLAlchemy, migrate and/or your particular database vendor.

Commands

To run a migrate command, use the following basic structure:

paster migrate development.ini command [--dburi] [--repository] [--version] [options]

For development.ini substitute the name of whatever configuration file you are using.

Common options are:

--dburi : the SQLAlchemy URI for your database. If not provided, then the sqlalchemy.dburi setting in the config file is used.

--repository: the directory for storing migrate scripts. By default, this is myapp/repository in your application root directory.

--version: the version to run your scripts on, if not the current version

Commands available through paster:

script script_path : creates a new Python or SQL migration script

test script_path : runs a migration script (upgrade/downgrade)

commit script_path : commits the script to the repository

source [dest]: prints script for latest/specified version to dest (or STDOUT)

drop_db_versioning : removes versioning info from database

upgrade : runs script upgrade to next version

downgrade : runs script downgrade to previous version

version : returns current repository version

db_version : returns current database version

Refer to the migrate documentation for more details on each of these commands.

When any of these commands are run, Tesla will check if the repository directory and database versioning table have been created, and will take care of creating them for you. You do not need to do any of the setup tasks you would normally have to do with migrate.

Strategies

It's worth considering a few things when using migrate in conjunction with Tesla:

  1. If you have used migrations with Rails' ActiveRecord (or similar frameworks) you will have used the migration system for creating new tables. This is mostly unnecessary here, because Elixir will automatically generate tables for you (including join tables). In Tesla, this is done when model.connect() is called when you run your application (the exception to this is if you are using the SQLAlchemy autoload feature). Instead use migrate to add and remove columns, drop unused tables, change table and column names, and other such housekeeping required to keep your production database schema and resident data current with the definitions in your model code. When inserting default data from scratch in a fresh database, it's probably better to use websetup.py and paster setup-app.

  2. Keep your model and migration code completely separate. In other words, do not do something like this:

from sqlalchemy import * from migrate import * from myapp.models import mymodel

This is likely to break when data definitions in the models get out of step with current database schema. If you need some model logic in your migration scripts then copy and paste that over. This may seem crude, but it prevents all kinds of versioning pain.

  1. Always run migration tests on a copy of your production database. Remember that migrate will run both upgrade and downgrade functions when testing, if these break then so does your database.