alembic 教程
用來做 orm 模型與數(shù)據(jù)庫的遷移與映射。使用方式跟 git類似,表現(xiàn)在兩個方面:
- alembic 的所有命令都以 alembic 開頭;
- alembic 的遷移文件也是銅鼓版本進(jìn)行控制的。
安裝方式:
pip install alembic
用法:
- 初始化 alembic 倉庫:
在終端中,cd 到項(xiàng)目目錄,然后執(zhí)行 alembic init alembic,創(chuàng)建一個名字叫 alembic 的倉庫。
- 創(chuàng)建模型類: 創(chuàng)建一個 models.py 模塊,然后在里面定義自己的模型。示例如下:
engine = create_engine(DB_URI) # 創(chuàng)建數(shù)據(jù)庫引擎
Base = declarative_base(engine) # 基類
class User(Base):
__tablename__ = 'user'
id = Column(Integer, autoincrement=True, primary_key=True)
name = Column(String(30), nullable=False)
age = Column(Integer, default=0)
def __init__(self, id, name):
self.id = id
self.name = name
def __repr__(self):
return "<User (name:{})>".format(self.name)
- 修改配置文件:
- 在 alembic.ini中設(shè)置數(shù)據(jù)庫的連接,
sqlalchemy.url = driver://user:pass@localhost/dbname,示例如下:
sqlalchemy.url = mysql+mysqldb://root:chenkuan1110@localhost/alembic_demo?charset=utf8
- 為了使模型類跟新到數(shù)據(jù)庫,需要在 env.py 文件中設(shè)置 target_metadata,默認(rèn)為target_metadata=None。
from models import Base
... # 省略代碼
target_metadata = Base.metadata # 設(shè)置創(chuàng)建模型的元類
... # 省略代碼
自動生成遷移文件: 使用
alembic revision --autogenerate -m 'message'將當(dāng)前模型中的狀態(tài)生成遷移文件。跟新數(shù)據(jù)庫: 使用
alembic upgrade head將剛剛生成的遷移文件,真正導(dǎo)入數(shù)據(jù)庫中。
同理,如果需要降級,那么使用alembic downgrade head。修改代碼后,重復(fù)操作 4~5的步驟。
-
命令和參數(shù)解釋:
- init: 創(chuàng)建一個 alembic 倉庫。
- revision: 創(chuàng)建一個新的版本文件。
- --autogenerate: 自動將當(dāng)前模型的修改,生成遷移腳本。
- -m : 本次遷移做了哪些修改,可以可以指定這個參數(shù),方便回顧。
- upgrade :將指定版本的遷移文件映射到數(shù)據(jù)庫中,會執(zhí)行版本文件的 upgrade 函數(shù)。
- head: 代表當(dāng)前的遷移版本的版本號。
- downgrade: 會執(zhí)行指定版本的文件中的 downgrade 函數(shù)。
- heads : 展示當(dāng)前可用的 heads 腳本文件。
- history : 列出所有的遷移版本及其信息。
- current :展示當(dāng)前數(shù)據(jù)庫中的版本號。
另外,在第一次執(zhí)行 upgrade 的時候會在數(shù)據(jù)庫中創(chuàng)建一個叫做 alembic_version 表,這個表只有一個數(shù)據(jù),記錄當(dāng)前數(shù)據(jù)庫映射的是哪個版本的遷移文件。
經(jīng)典錯誤:
| 錯誤描述 | 原因 | 解決辦法 |
|---|---|---|
| FAILED: Target database is not up to data. | 主要原因是 heads 和 current 不相同。 current 落后于 heads 版本。 | 將 current 移動到 head上。 alembic upgrad head
|
| FAILED: Can't locate revision identifed by 'xxxxxxx' | 數(shù)據(jù)庫中存的版本號不在遷移腳本文件中 | 刪除數(shù)據(jù)庫中 alembic_version 表中的數(shù)據(jù),重新執(zhí)行 alembic upgrade head
|