Alembic でデフォルト値を設定する

今までスキーマーの管理は普通に SQL ファイルで管理していた。
別に DDL を書くのは苦痛じゃないし分かり易いので良いんだけど、マイグレーションツールに Alembic を使ってみようと試している。

"""Create users table.

Revision ID: 197f6c68376
Revises: None
Create Date: 2014-01-31 23:31:09.715707

"""

# revision identifiers, used by Alembic.
revision = '197f6c68376'
down_revision = None

from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects.mysql import INTEGER as Integer


def upgrade():
    op.create_table(
        'users',
        sa.Column('id', sa.Integer, primary_key=True),
        sa.Column('name', sa.String(50), nullable=False, index=True),
        sa.Column('password', sa.String(128), nullable=False, index=True),
        sa.Column('email', sa.String(254), nullable=False, index=True),
        sa.Column('role', Integer(4), default=100)),
        sa.Column('delete_flag', sa.Boolean, default=0),
        sa.Column('created_at', sa.DateTime),
        sa.Column('updated_at', sa.DateTime)
    )


def downgrade():
    op.drop_table('users')

こんな感じで作って、

$ alembic upgrade head

したら、以下のようなスキーマが出来た。

CREATE TABLE `users` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
  `password` varchar(128) COLLATE utf8_unicode_ci NOT NULL,
  `email` varchar(254) COLLATE utf8_unicode_ci NOT NULL,
  `role` int(4) DEFAULT NULL,
  `delete_flag` tinyint(1) DEFAULT NULL,
  `created_at` datetime DEFAULT NULL,
  `updated_at` datetime DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `ix_users_password` (`password`),
  KEY `ix_users_name` (`name`),
  KEY `ix_users_email` (`email`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

delete_flag と role の所が DEFAUL NULL になっている。


default でなくて server_default とすれば行けた。

def upgrade():
    op.create_table(
        'users',
        sa.Column('id', sa.Integer, primary_key=True),
        sa.Column('name', sa.String(50), nullable=False, index=True),
        sa.Column('password', sa.String(128), nullable=False, index=True),
        sa.Column('email', sa.String(254), nullable=False, index=True),
        sa.Column('role', Integer(4), server_default=sa.text('100')),
        sa.Column('delete_flag', sa.Boolean, server_default='0'),
        sa.Column('created_at', sa.DateTime),
        sa.Column('updated_at', sa.DateTime)
    )

Alembic というか SQLAlchemy の tips かも。