Alembic

起步

安裝

pip install alembic

# 初始化
alembic init alembic

配置

  • 修改配置alembic.ini
[alembic]
sqlalchemy.url = driver://user:pass@localhost/dbname
# 如下,修改為當(dāng)前使用的sql數(shù)據(jù)庫連接url
# sqlalchemy.url = postgresql://user:pass@localhost/dbname
  • 修改配置alembic/env.py
    • 搜索"target_metadata"找到代碼
    • 如下是使用SQLModel
# 導(dǎo)入SQLModel,及自定義模型
from sqlmodel import SQLModel
from model.user import User

# target_metadata = None
target_metadata = SQLModel.metadata

遷移

  • 創(chuàng)建遷移數(shù)據(jù)
    • 通過對比數(shù)據(jù)庫表信息與所有遷移文件拐云,計算出差異字段后再生成新的遷移文件
  • 首次使用甘耿,如果數(shù)據(jù)庫中已經(jīng)有表君躺,會影響首次遷移文件
    • 建議先連接空數(shù)據(jù)庫第晰,生成遷移文件(記錄下alembic_version表的生成SQL谓苟,在數(shù)據(jù)庫中插入表)
    • 將版本號加到"alembic_version"表中涕癣,就不會運(yùn)行重復(fù)執(zhí)行了
# 創(chuàng)建新記錄哗蜈,并添加表格遷移信息(--autogenerate)
alembic revision -m "add_xxx" --autogenerate
# 在alembic/versions目錄下生成一個遷移文件

# 升級
alembic upgrade head
# 創(chuàng)建almebic_version的表(如果不存在)
# 應(yīng)用遷移文件

# 僅打印sql文件,但暫不修改數(shù)據(jù)庫
alembic upgrade head --sql


# 降級
alembic downgrade <version>
# version在生成遷移文件里坠韩,找到down_revision字段
  • 手動創(chuàng)建數(shù)據(jù)表如下
    • 最好是連接空數(shù)據(jù)庫距潘,再記錄生成的SQL語句(需要引擎echo=True)
# 手動插入alembic數(shù)據(jù)表(Postgresql)
CREATE TABLE alembic_version (
        version_num VARCHAR(32) NOT NULL,
        CONSTRAINT alembic_version_pkc PRIMARY KEY (version_num)
);

# 插入版本號
INSERT INTO alembic_version (version_num) VALUES ('2fee77670444');

遷移

生成默認(rèn)值

  • 想在已有數(shù)據(jù)的表中增加列,新增的列因為性能問題不為空只搁,需要設(shè)置個默認(rèn)值
from sqlmodel import SQLModel, Field, BigInteger, Integer, String

class User(SQLModel, table=True):
    __tablename__ = "user"
    id: int | None = Field(sa_type=BigInteger, default=None, primary_key=True)
    name: str = Field(sa_type=String(32), default="")

    # 新增年齡這一列
    age: int = Field(sa_type=Integer, default=0, sa_column_kwargs={"comment": "年齡"})
  • 修改生成的代碼音比,"age"字段中,增加"server_default"
    * "default"字段在代碼端生效氢惋,比如插入記錄時洞翩,賦值默認(rèn)值
    * "server_default"是設(shè)置數(shù)據(jù)庫端的默認(rèn)值稽犁,生成"... DEFAULT '0' ..."的SQL語句
    * "server_default"只能是str/ClauseElement/TextClause(報錯會打印),將字符串設(shè)置為SQL語句中單引號內(nèi)得值即
# ...略

def upgrade() -> None:
    op.add_column(
        "user",
        sa.Column(
            "age",
            sa.Integer(),
            nullable=False,
            comment="年齡",
            server_default="0",  # 手動添加該默認(rèn)值字段(使用default無效菱农,因為是代碼端生效)
        ),
    )
    # 或者直接寫SQL語句
    op.execute("ALTER TABLE \"user\" ADD COLUMN age INTEGER DEFAULT '0' NOT NULL")

def downgrade() -> None:
    op.drop_column("user", "age")
  • 生成語句
ALTER TABLE "user" ADD COLUMN age INTEGER DEFAULT '0' NOT NULL

配置

alembic.ini

[alembic]
# 文件命名格式缭付,默認(rèn)版本號是隨機(jī)的不方便查看,建議如下設(shè)置循未,文件格式"20241206-init-c28e8488d2bc.py"
file_template = %%(year)d%%(month).2d%%(day).2d-%%(slug)s-%%(rev)s

# 數(shù)據(jù)庫連接字符串陷猫,項目中不建議使用,而是在"alembic/env.py"切換到統(tǒng)一環(huán)境變量管理
sqlalchemy.url = driver://user:pass@localhost/dbname

alembic/env.py

  • 設(shè)置元數(shù)據(jù)
# 初始值
# target_metadata = None


# 修改為
from sqlmodel import SQLModel   # 或者導(dǎo)入sqlalchemy對應(yīng)的metadata
# 導(dǎo)入其他表對象的妖,如
# from models import User

target_metadata = SQLModel.metadata
  • 數(shù)據(jù)庫連接
# 該方法在"alembic upgrade head --sql"生效(有--sql參數(shù))
def run_migrations_offline() -> None:
    # url = config.get_main_option("sqlalchemy.url")
    # 數(shù)據(jù)庫連接從統(tǒng)一環(huán)境變量獲取
    from setting import get_setting
    url = get_setting().db_url

    # 僅修改url來源绣檬,其他代碼不變

# 該方法在"alembic upgrade head"生效(無--sql參數(shù))
def run_migrations_online() -> None:
    # connectable = engine_from_config(
    #     config.get_section(config.config_ini_section, {}),
    #     prefix="sqlalchemy.",
    #     poolclass=pool.NullPool,
    # )
    # 從自己項目導(dǎo)入數(shù)據(jù)庫引擎
    from database import engine
    connectable = engine

    # 僅修改engine(其實也是改url來源),其他代碼不變

參考文檔

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末嫂粟,一起剝皮案震驚了整個濱河市娇未,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌星虹,老刑警劉巖零抬,帶你破解...
    沈念sama閱讀 216,402評論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異宽涌,居然都是意外死亡平夜,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評論 3 392
  • 文/潘曉璐 我一進(jìn)店門卸亮,熙熙樓的掌柜王于貴愁眉苦臉地迎上來忽妒,“玉大人,你說我怎么就攤上這事兼贸《沃保” “怎么了?”我有些...
    開封第一講書人閱讀 162,483評論 0 353
  • 文/不壞的土叔 我叫張陵溶诞,是天一觀的道長鸯檬。 經(jīng)常有香客問我,道長螺垢,這世上最難降的妖魔是什么京闰? 我笑而不...
    開封第一講書人閱讀 58,165評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮甩苛,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘俏站。我一直安慰自己讯蒲,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,176評論 6 388
  • 文/花漫 我一把揭開白布肄扎。 她就那樣靜靜地躺著墨林,像睡著了一般赁酝。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上旭等,一...
    開封第一講書人閱讀 51,146評論 1 297
  • 那天酌呆,我揣著相機(jī)與錄音,去河邊找鬼搔耕。 笑死隙袁,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的弃榨。 我是一名探鬼主播菩收,決...
    沈念sama閱讀 40,032評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼鲸睛!你這毒婦竟也來了娜饵?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,896評論 0 274
  • 序言:老撾萬榮一對情侶失蹤官辈,失蹤者是張志新(化名)和其女友劉穎箱舞,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體拳亿,經(jīng)...
    沈念sama閱讀 45,311評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡晴股,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,536評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了风瘦。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片队魏。...
    茶點故事閱讀 39,696評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖万搔,靈堂內(nèi)的尸體忽然破棺而出胡桨,到底是詐尸還是另有隱情,我是刑警寧澤瞬雹,帶...
    沈念sama閱讀 35,413評論 5 343
  • 正文 年R本政府宣布昧谊,位于F島的核電站,受9級特大地震影響酗捌,放射性物質(zhì)發(fā)生泄漏呢诬。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,008評論 3 325
  • 文/蒙蒙 一胖缤、第九天 我趴在偏房一處隱蔽的房頂上張望尚镰。 院中可真熱鬧,春花似錦哪廓、人聲如沸狗唉。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽分俯。三九已至肾筐,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間缸剪,已是汗流浹背吗铐。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留杏节,地道東北人唬渗。 一個月前我還...
    沈念sama閱讀 47,698評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像拢锹,于是被迫代替她去往敵國和親谣妻。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,592評論 2 353

推薦閱讀更多精彩內(nèi)容