[note] Python SQLAlchemy & Alembic
[toc]
參考資料
以 PostgreSQL 為例
Prerequisites
安裝需要用到的套件
$ poetry add SQLAlchemy psycopg2-binary
使用 Docker 啟動 PostgreSQL
$ docker run --name postgres -e POSTGRES_PASSWORD=postgres -e POSTGRES_USER=admin -e POSTGRES_DB=dev -p 5432:5432 -d postgres
使用 Alembic
CLI
# 初始化 alembic
$ alembic init alembic
# 建立 migration script 來追蹤 database schema 的改變
$ alembic revision --autogenerate -m "initial migration"
# alembic upgrade <revision>
$ alembic upgrade head # 除了用 head(latest revision)外,也可以用 +2 或 revision_id
# alembic downgrade <revision>
$ alembic downgrade -1 # 也可以用 revision_id 或 base(回到最初始的狀態)
$ alembic heads # 顯示目前所有的 heads
$ alembic merge heads # merge heads
$ alembic current # 顯示目前 migration 的狀態
$ alembic history # 顯示 migration history
修改 alembic 中的 env.py 檔
在 /alembic/env.py
中需要
- 定義連線到 database 的方法
- 讓 alembic 可以讀到 database 的 metadata(
target_metadata
)
diff --git a/alembic/env.py b/alembic/env.py
index dd0f6ba..346ea44 100644
--- a/alembic/env.py
+++ b/alembic/env.py
@@ -1,6 +1,7 @@
from logging.config import fileConfig
-from sqlalchemy import engine_from_config
+from environs import Env
+from sqlalchemy import engine_from_config, URL
from sqlalchemy import pool
from alembic import context
@@ -14,11 +15,29 @@ config = context.config
if config.config_file_name is not None:
fileConfig(config.config_file_name)
+env = Env()
+env.read_env(".env")
+
+url = URL.create(
+ drivername="postgresql",
+ username=env.str("POSTGRES_USER"),
+ password=env.str("POSTGRES_PASSWORD"),
+ host=env.str("DATABASE_HOST"),
+ database=env.str("POSTGRES_DB"),
+ port=5432
+)
+
+config.set_main_option(
+ "sqlalchemy.url", url.render_as_string(hide_password=False)
+)
+
# add your model's MetaData object here
# for 'autogenerate' support
# from myapp import mymodel
# target_metadata = mymodel.Base.metadata
-target_metadata = None
+import lesson_2
+
+target_metadata = lesson_2.Base.metadata
使用 SQLAlchemy
官方文件
- ORM Quick Start: A glimpse at what working with the ORM looks like
- SQLAlchemy Unified Tutorial: In depth tutorial for Core and ORM
Execute SQL in the App
與 database 建立連線
- 建立 connection URL
- 建立 engine
- 建立 session
from sqlalchemy import URL, create_engine, text
from sqlalchemy.orm import sessionmaker
url = URL.create(
drivername="postgresql",
username="admin",
password="postgres",
host="localhost",
database="dev",
port=5432
)
url.render_as_string(hide_password=False) # postgresql://admin:***@localhost:5432/dev
engine = create_engine(url, echo=True)
Session = sessionmaker(engine)
with Session() as session:
# do something with the session...