Skip to content

Commit 8736b75

Browse files
committed
feat: add alembic
1 parent 713e44f commit 8736b75

File tree

7 files changed

+464
-9
lines changed

7 files changed

+464
-9
lines changed

migrate/README.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,44 @@
11

22
# BirdXplorer Migrations
3+
4+
## Alembic によるマイグレーション
5+
6+
### 前提条件
7+
8+
- `birdxplorer_common` のインストールが完了していること
9+
- `birdxplorer_migration` のインストールが完了していること
10+
- `.env` ファイルに `BX_STORAGE_SETTINGS__PASSWORD` が設定されていること
11+
- DB のデフォルトホスト名 `db` が解決できない場合は `BX_STORAGE_SETTINGS__HOST` も設定すること
12+
13+
### 現在のマイグレーションを適用する
14+
15+
データベースのスキーマを最新の状態にします。
16+
17+
`alembic.ini` があるディレクトリの場合:
18+
19+
```bash
20+
alembic upgrade head
21+
```
22+
23+
`alembic.ini` が別の場所にある場合:
24+
25+
```bash
26+
alembic upgrade head -c /path/to/alembic.ini
27+
```
28+
29+
### 新しいマイグレーションを作成する
30+
31+
データベースのスキーマを変更した場合、以下の手順で新しいマイグレーションを作成します。
32+
33+
`alembic.ini` があるディレクトリの場合:
34+
35+
```bash
36+
alembic revision --autogenerate -m "マイグレーションの説明"
37+
```
38+
39+
`alembic.ini` が別の場所にある場合:
40+
41+
```bash
42+
alembic revision --autogenerate -m "マイグレーションの説明" -c /path/to/alembic.ini
43+
```
44+

migrate/alembic.ini

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
[alembic]
2+
script_location = %(here)s/migration
3+
4+
[loggers]
5+
keys = root,sqlalchemy,alembic
6+
7+
[handlers]
8+
keys = console
9+
10+
[formatters]
11+
keys = generic
12+
13+
[logger_root]
14+
level = WARNING
15+
handlers = console
16+
qualname =
17+
18+
[logger_sqlalchemy]
19+
level = WARNING
20+
handlers =
21+
qualname = sqlalchemy.engine
22+
23+
[logger_alembic]
24+
level = INFO
25+
handlers =
26+
qualname = alembic
27+
28+
[handler_console]
29+
class = StreamHandler
30+
args = (sys.stderr,)
31+
level = NOTSET
32+
formatter = generic
33+
34+
[formatter_generic]
35+
format = %(levelname)-5.5s [%(name)s] %(message)s
36+
datefmt = %H:%M:%S
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = "0.0.1"
1+
__version__ = "0.1.0"

migrate/migration/env.py

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
import os
2+
from logging.config import fileConfig
3+
4+
from alembic import context
5+
from dotenv import load_dotenv
6+
7+
from birdxplorer_common.settings import GlobalSettings
8+
from birdxplorer_common.storage import Base, gen_storage
9+
10+
# this is the Alembic Config object, which provides
11+
# access to the values within the .ini file in use.
12+
config = context.config
13+
14+
# Interpret the config file for Python logging.
15+
# This line sets up loggers basically.
16+
if config.config_file_name is not None:
17+
fileConfig(config.config_file_name)
18+
19+
work_dir = os.path.dirname(os.path.abspath(__file__))
20+
env_file = os.path.join(os.path.dirname(os.path.dirname(work_dir)), ".env")
21+
load_dotenv(env_file)
22+
bx_settings = GlobalSettings()
23+
24+
# add your model's MetaData object here
25+
# for 'autogenerate' support
26+
# from myapp import mymodel
27+
# target_metadata = mymodel.Base.metadata
28+
target_metadata = Base.metadata
29+
30+
# other values from the config, defined by the needs of env.py,
31+
# can be acquired:
32+
# my_important_option = config.get_main_option("my_important_option")
33+
# ... etc.
34+
35+
36+
def run_migrations_offline() -> None:
37+
"""Run migrations in 'offline' mode.
38+
39+
This configures the context with just a URL
40+
and not an Engine, though an Engine is acceptable
41+
here as well. By skipping the Engine creation
42+
we don't even need a DBAPI to be available.
43+
44+
Calls to context.execute() here emit the given string to the
45+
script output.
46+
47+
"""
48+
url = bx_settings.storage_settings.sqlalchemy_database_url
49+
context.configure(
50+
url=url,
51+
target_metadata=target_metadata,
52+
literal_binds=True,
53+
dialect_opts={"paramstyle": "named"},
54+
)
55+
56+
with context.begin_transaction():
57+
context.run_migrations()
58+
59+
60+
def run_migrations_online() -> None:
61+
"""Run migrations in 'online' mode.
62+
63+
In this scenario we need to create an Engine
64+
and associate a connection with the context.
65+
66+
"""
67+
storage = gen_storage(settings=bx_settings)
68+
connectable = storage.engine
69+
70+
with connectable.connect() as connection:
71+
context.configure(connection=connection, target_metadata=target_metadata)
72+
73+
with context.begin_transaction():
74+
context.run_migrations()
75+
76+
77+
if context.is_offline_mode():
78+
run_migrations_offline()
79+
else:
80+
run_migrations_online()

migrate/migration/script.py.mako

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
"""${message}
2+
3+
Revision ID: ${up_revision}
4+
Revises: ${down_revision | comma,n}
5+
Create Date: ${create_date}
6+
7+
"""
8+
from typing import Sequence, Union
9+
10+
from alembic import op
11+
import sqlalchemy as sa
12+
${imports if imports else ""}
13+
14+
# revision identifiers, used by Alembic.
15+
revision: str = ${repr(up_revision)}
16+
down_revision: Union[str, None] = ${repr(down_revision)}
17+
branch_labels: Union[str, Sequence[str], None] = ${repr(branch_labels)}
18+
depends_on: Union[str, Sequence[str], None] = ${repr(depends_on)}
19+
20+
21+
def upgrade() -> None:
22+
${upgrades if upgrades else "pass"}
23+
24+
25+
def downgrade() -> None:
26+
${downgrades if downgrades else "pass"}

0 commit comments

Comments
 (0)