使用alembic

alembic是SQLAlchemy的作者写的migrate库。

我是在尝试了解SQLAlchemy-migrate时发现这么一个库的。因为SQLAlchemy-migrate项目说明说,如果你是开始一个新项目的话,推荐使用alembic.

(1)首先安装:

yautous-Mac-mini:microblog yautou$ flask/bin/pip install alembic

Downloading/unpacking alembic
  Downloading alembic-0.5.0.tar.gz (387kB): 387kB downloaded
  Running setup.py egg_info for package alembic
。。。。。。。
yautous-Mac-mini:microblog yautou$ ls

app/  config.py  config.pyc  db_create.py*  flask/  run.py*  tmp/  virtualenv.py  virtualenv.pyc


(2)然后初始化。  yautous-Mac-mini:microblog yautou$ flask/bin/alembic init alembic 

  Creating directory /Users/yautou/work/python/microblog/alembic...done
  Creating directory /Users/yautou/work/python/microblog/alembic/versions...done
  Generating /Users/yautou/work/python/microblog/alembic.ini...done
  Generating /Users/yautou/work/python/microblog/alembic/env.py...done
  Generating /Users/yautou/work/python/microblog/alembic/env.pyc...done
  Generating /Users/yautou/work/python/microblog/alembic/README...done
  Generating /Users/yautou/work/python/microblog/alembic/script.py.mako...done
  Please edit configuration/connection/logging settings in
  '/Users/yautou/work/python/microblog/alembic.ini' before proceeding.

yautous-Mac-mini:microblog yautou$ 

 (3)配置SQLAlchemy的url。

    vi alembic.ini

    sqlalchemy.url = "sqlite:///app.db"

  对于sqlite来讲使用相对位置的话以sqlite:///开头,使用绝对位置的话使用sqlite:开头。

  对于其它数据来说url应该是这样的:

sqlalchemy.url = driver://user:pass@localhost/dbname


(4)编写迁移脚本

yautous-Mac-mini:microblog yautou$ flask/bin/alembic  revision -m"create user table"


yautous-Mac-mini:microblog yautou$ cat alembic/versions/32650e9fdf67_create_user_table.py
"""create user table

Revision ID: 32650e9fdf67
Revises: None
Create Date: 2013-05-01 11:55:33.111931

"""

# revision identifiers, used by Alembic.
revision = '32650e9fdf67'
down_revision = None

from alembic import op
import sqlalchemy as sa


def upgrade():
    op.create_table(
            'user',
            sa.Column('id',sa.Integer,primary_key=True),
            sa.Column('nickname',sa.String(64),nullable=False,unique=True,index=True),
            sa.Column('email',sa.String(120),index=True,unique=True),
            sa.Column('role',sa.SmallInteger,default=0),

            )


def downgrade():
    op.drop_table('user')
yautous-Mac-mini:microblog yautou$


(5)进行首次迁移

yautous-Mac-mini:microblog yautou$ vi alembic/versions/32650e9fdf67_create_user_table.py 
yautous-Mac-mini:microblog yautou$ flask/bin/alembic  upgrade head
INFO  [alembic.migration] Context impl SQLiteImpl.
INFO  [alembic.migration] Will assume non-transactional DDL.
INFO  [sqlalchemy.engine.base.Engine] PRAGMA table_info("alembic_version")
INFO  [sqlalchemy.engine.base.Engine] ()
DEBUG [sqlalchemy.engine.base.Engine] Col ('cid', 'name', 'type', 'notnull', 'dflt_value', 'pk')
DEBUG [sqlalchemy.engine.base.Engine] Row (0, u'version_num', u'VARCHAR(32)', 1, None, 0)
INFO  [sqlalchemy.engine.base.Engine] SELECT alembic_version.version_num 
FROM alembic_version
INFO  [sqlalchemy.engine.base.Engine] ()
DEBUG [sqlalchemy.engine.base.Engine] Col ('version_num',)
INFO  [alembic.migration] Running upgrade None -> 32650e9fdf67, create user table
INFO  [sqlalchemy.engine.base.Engine] 
CREATE TABLE user (
	id INTEGER NOT NULL, 
	nickname VARCHAR(64) NOT NULL, 
	email VARCHAR(120), 
	role SMALLINT, 
	PRIMARY KEY (id)
)


INFO  [sqlalchemy.engine.base.Engine] ()
INFO  [sqlalchemy.engine.base.Engine] COMMIT
INFO  [sqlalchemy.engine.base.Engine] CREATE UNIQUE INDEX ix_user_nickname ON user (nickname)
INFO  [sqlalchemy.engine.base.Engine] ()
INFO  [sqlalchemy.engine.base.Engine] COMMIT
INFO  [sqlalchemy.engine.base.Engine] CREATE UNIQUE INDEX ix_user_email ON user (email)
INFO  [sqlalchemy.engine.base.Engine] ()
INFO  [sqlalchemy.engine.base.Engine] COMMIT
INFO  [sqlalchemy.engine.base.Engine] INSERT INTO alembic_version (version_num) VALUES ('32650e9fdf67')
INFO  [sqlalchemy.engine.base.Engine] ()
INFO  [sqlalchemy.engine.base.Engine] COMMIT
yautous-Mac-mini:microblog yautou$


上面的这种做法,是基本的,

我们还可以让它更智能点,根据我们的model的变化来自动生成更新脚本。

这个时候我们只需要修改下alembic/env.py这个文件的配置就可以了。

target_metadata = None
改为:

from app import db
target_metadata = db.metadata
值得注意的是。

alembic/env.py这个文件并不能知道我们的app模块的位置。

所以,我们还需要多写一点代码。

import os
import sys

root = os.path.dirname(__file__) + '/../'
print root

sys.path.append(root)

此时我们的app/__init__.py文件内容如下:

#-*- coding:utf-8 -*-
from flask import Flask
from flask.ext.sqlalchemy import SQLAlchemy

server = Flask(__name__)
server.config.from_object('config')
db = SQLAlchemy(server)

from app import views,models

app/models.py如下:

#-*- coding:utf-8 -*-
from app import db


ROLE_USER = 0
ROLE_ADMIN = 1


class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    nickname = db.Column(db.String(64), index=True, unique=True)
    email = db.Column(db.String(120), index=True, unique=True)
    role = db.Column(db.SmallInteger, default=ROLE_USER)
    posts = db.relationship('Post', backref='author', lazy='dynamic')

    def __repr__(self):
        return "<User %r>" % (self.nickname)


class Post(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    body = db.Column(db.String(140))
    timestamp = db.Column(db.DateTime)
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'))

    def __repr__(self):
        return '<Post %r>' % (self.body)

当我们修改了model时,我们运行下:

$ flask/bin/alembic revision -m" comment message "

然后,你可以查看下生成的脚本。看是否还需要手动修改。

然后运行$ flask/bin/alembic upgrade head

数据库就更新了。

注意:alembic目前还不能处理所以的数据库自动检查更新。

例如你将一列改名了。它会认为只是删除后添加了新的列。

转载于:https://my.oschina.net/banxi/blog/126695

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值