Skip to content

Commit 044aecf

Browse files
committed
call yoyo from code, wip sqlalchemy-core
1 parent acd391c commit 044aecf

File tree

10 files changed

+508
-5
lines changed

10 files changed

+508
-5
lines changed

README.md

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,14 @@ This is suitable for:
2828
- [ ] knex.js?
2929
- [ ] https://sqorn.org/benchmarks.html ?
3030
- [ ] Example python code to use this cluster
31-
- [x] using psycopg3 directly
32-
- [x] using yoyo migrations
31+
- `./python-psycopg3`
32+
- [x] using psycopg3 directly
33+
- [x] using yoyo migrations through terminal
34+
- docker exec into the container to run the `yoyo` cli
3335
- ~~[ ] sqlalchemy core and alembic? (alembic is too coupled with sqlalchemy for my taste)~~
34-
- [ ] sqlalchemy core and yoyo-migrations?
36+
- `./python-sql-alchemy-core`
37+
- [x] yoyo migrations called from python code
38+
- [ ] sqlalchemy-core for data manipulation
3539

3640
### Prerequisites
3741

@@ -140,8 +144,19 @@ Using yoyo migrations:
140144
```
141145
1. Also possible to [perform migrations using code](https://ollycope.com/software/yoyo/latest/#calling-yoyo-from-python-code)
142146
143-
#### More clients WIP
147+
#### Python sqlalchemy client
144148
149+
1. Reset all yoyo tables in the database (if yoyo cli was run in the psycopg3
150+
client test).
151+
- docker exec into one of the cockroachdb instances (see above)
152+
- `\c test_app`: Connect to the `test_app` database
153+
- `\dt`: List tables
154+
- `DROP TABLE IF EXISTS _yoyo_log, _yoyo_migration, _yoyo_version, yoyo_lock`
155+
1. `docker compose -f ./python-sqlalchemy-core/docker-compose.yml up --build`
156+
1. (WIP) see some logs...
157+
1. `docker compose -f ./python-sqlalchemy-core/docker-compose.yml down`
158+
159+
#### More Clients WIP
145160
146161
### Stop the Cluster
147162

python-psycopg3/yoyo.ini

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[DEFAULT]
22
sources = migrations
33
database = postgresql+psycopg://%(DB_USER)s:%(DB_PSWD)s@%(DB_HOST)s/%(DB_NAME)s
4-
batch_mode = off
4+
batch_mode = off # "on" disable interactive features
55
verbosity = 0

python-sqlalchemy-core/Dockerfile

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
FROM debian:12.1-slim
2+
3+
ENV PYTHONUNBUFFERED=1
4+
ENV NODE_ENV=production
5+
6+
RUN apt-get update -y \
7+
&& apt-get install -y \
8+
dumb-init vim curl \
9+
python3 python3-pip \
10+
&& rm -rf /var/lib/apt/lists/*
11+
12+
RUN mkdir -p /workspace/src \
13+
&& curl -sSL https://install.python-poetry.org | python3 - --version 1.6.1
14+
# set poetry path
15+
ENV PATH="/root/.local/bin:$PATH"
16+
17+
WORKDIR /workspace
18+
COPY pyproject.toml poetry.lock /workspace/
19+
20+
RUN poetry install
21+
22+
# Set up migrations
23+
# COPY ./yoyo.ini /workspace/yoyo.ini
24+
25+
COPY ./src /workspace/src/
26+
27+
ENTRYPOINT [ "dumb-init", "--" ]
28+
29+
CMD [ "poetry", "run", "python3", "src/main.py" ]
30+
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
networks:
2+
default:
3+
name: cockroachdb-net
4+
external: true
5+
6+
services:
7+
python-psycopg3-client:
8+
image: python-psycopg3-client:latest
9+
build: .
10+
container_name: python-psycopg3-client
11+
environment:
12+
- DB_NAME=test_app
13+
- DB_USER=test_app_user
14+
- DB_PSWD=test_app_pswd
15+
- DB_HOST=cockroach-db.local:26257
16+
# for testing
17+
# - DB_HOST=postgres-db-1.local:5432
18+
networks:
19+
- default
20+

python-sqlalchemy-core/poetry.lock

Lines changed: 366 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

python-sqlalchemy-core/pyproject.toml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
[tool.poetry]
2+
name = "python-sqlalchemy-core"
3+
version = "0.1.0"
4+
description = ""
5+
authors = ["weipang <[email protected]>"]
6+
readme = "README.md"
7+
8+
[tool.poetry.dependencies]
9+
python = "^3.11"
10+
yoyo-migrations = "^8.2.0"
11+
psycopg = {extras = ["binary", "pool"], version = "^3.1.12"}
12+
sqlalchemy = {extras = ["asyncio"], version = "^2.0.21"}
13+
14+
15+
[build-system]
16+
requires = ["poetry-core"]
17+
build-backend = "poetry.core.masonry.api"

python-sqlalchemy-core/src/main.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
from yoyo import read_migrations
2+
from yoyo import get_backend
3+
4+
import os
5+
import asyncio
6+
7+
async def async_main():
8+
while True:
9+
print('hello world')
10+
await asyncio.sleep(2)
11+
12+
def main():
13+
asyncio.run(async_main())
14+
15+
if __name__ == '__main__':
16+
17+
DB_USER = os.environ['DB_USER']
18+
DB_PSWD = os.environ['DB_PSWD']
19+
DB_HOST = os.environ['DB_HOST']
20+
DB_NAME = os.environ['DB_NAME']
21+
22+
backend = get_backend(f'postgresql+psycopg://{DB_USER}:{DB_PSWD}@{DB_HOST}/{DB_NAME}')
23+
migrations = read_migrations('/workspace/src/migrations')
24+
25+
with backend.lock():
26+
27+
# Apply any outstanding migrations
28+
backend.apply_migrations(backend.to_apply(migrations))
29+
30+
# Rollback all migrations
31+
# backend.rollback_migrations(backend.to_rollback(migrations))
32+
33+
main()
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
from yoyo import step
2+
3+
# Using python is more flexible and allows being more explicit intent when
4+
# defining migration scripts.
5+
# https://ollycope.com/software/yoyo/latest/#migrations-as-python-scripts
6+
7+
apply = 'CREATE TABLE test_sqlalchemy (id INT, value VARCHAR(20), value2 INT, PRIMARY KEY (id))'
8+
rollback = 'DROP TABLE test_sqlalchemy'
9+
10+
steps = [
11+
step(apply, rollback)
12+
]
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
from yoyo import step
2+
3+
__depends__ = {"0000-initial_schema"}
4+
5+
apply = 'ALTER TABLE test_sqlalchemy ADD COLUMN new_column BOOLEAN NOT NULL DEFAULT TRUE'
6+
rollback = 'ALTER TABLE test_sqlalchemy DROP COLUMN new_column'
7+
8+
steps = [
9+
step(apply, rollback)
10+
]

0 commit comments

Comments
 (0)