diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml index adfe1b7..a446f09 100644 --- a/.github/workflows/build-and-test.yml +++ b/.github/workflows/build-and-test.yml @@ -24,6 +24,8 @@ jobs: options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5 steps: + - name: Create database schema + run: PGPASSWORD=secret psql -h 127.0.0.1 -d testdb -U user -c "CREATE SCHEMA shakespeare;" - uses: actions/checkout@v2 - name: Set up Python uses: actions/setup-python@v2 @@ -40,3 +42,5 @@ jobs: SQL_HOST: 127.0.0.1 SQL_USER: user POSTGRES_PASSWORD: secret + PGPASSWORD: secret + diff --git a/alembic/README b/alembic/README new file mode 100644 index 0000000..334cb7e --- /dev/null +++ b/alembic/README @@ -0,0 +1,16 @@ +Alembic commands +==================== + +### Check current revision +>alembic current + +### Make new revision +>alembic revision --autogenerate -m "first revision" + +After autogeneration it is highly recommended to check new revision in /versions/ folder, and adjust it if needed + +### Upgrade the DB to the newest revision +>alembic upgrade head + +### Downgrade DB to previous revision +>alembic downgrade -1 diff --git a/alembic/env.py b/alembic/env.py new file mode 100644 index 0000000..4d208a7 --- /dev/null +++ b/alembic/env.py @@ -0,0 +1,54 @@ +import asyncio + +from alembic import context +from sqlalchemy.ext.asyncio import create_async_engine + +from the_app.models.base import Base as app_base + +target_metadata = app_base.metadata + + +def run_migrations_offline(): + """Run migrations in 'offline' mode. + + This configures the context with just a URL + and not an Engine, though an Engine is acceptable + here as well. By skipping the Engine creation + we don't even need a DBAPI to be available. + + Calls to context.execute() here emit the given string to the + script output. + + """ + url = f"postgresql+asyncpg://user:secret@db:5432/devdb" + context.configure(url=url, target_metadata=target_metadata, literal_binds=True) + + with context.begin_transaction(): + context.run_migrations() + + +def do_run_migrations(connection): + context.configure(connection=connection, target_metadata=target_metadata) + + with context.begin_transaction(): + context.run_migrations() + + +async def run_migrations_online(): + """Run migrations in 'online' mode. + + In this scenario we need to create an Engine + and associate a connection with the context. + + """ + url = f"postgresql+asyncpg://user:secret@db:5432/devdb" + connectable = create_async_engine(url) + + async with connectable.connect() as connection: + await connection.run_sync(do_run_migrations) + + +if context.is_offline_mode(): + run_migrations_offline() +else: + asyncio.run(run_migrations_online()) diff --git a/alembic/script.py.mako b/alembic/script.py.mako new file mode 100644 index 0000000..0fdcfba --- /dev/null +++ b/alembic/script.py.mako @@ -0,0 +1,25 @@ +"""${message} + +Revision ID: ${up_revision} +Revises: ${down_revision | comma,n} +Create Date: ${create_date} + +""" +from alembic import op +import sqlalchemy as sa +import tm.db +${imports if imports else ""} + +# revision identifiers, used by Alembic. +revision = ${repr(up_revision)} +down_revision = ${repr(down_revision)} +branch_labels = ${repr(branch_labels)} +depends_on = ${repr(depends_on)} + + +def upgrade(): + ${upgrades if upgrades else "pass"} + + +def downgrade(): + ${downgrades if downgrades else "pass"} diff --git a/alembic/versions/.gitkeep b/alembic/versions/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/db/create.sql b/db/create.sql index 2cd7a40..6d6618e 100644 --- a/db/create.sql +++ b/db/create.sql @@ -1,4 +1,9 @@ DROP DATABASE IF EXISTS devdb; CREATE DATABASE devdb; +\connect devdb; +CREATE SCHEMA shakespeare; + DROP DATABASE IF EXISTS testdb; CREATE DATABASE testdb; +\connect testdb; +CREATE SCHEMA shakespeare; diff --git a/the_app/models/__init__.py b/the_app/models/__init__.py index 9a6ae8f..63287f6 100644 --- a/the_app/models/__init__.py +++ b/the_app/models/__init__.py @@ -1,2 +1,3 @@ from the_app.models.nonsense import Nonsense # noqa from the_app.models.stuff import Stuff # noqa +from the_app.models.shakespeare import Character # noqa diff --git a/the_app/models/shakespeare.py b/the_app/models/shakespeare.py index 3d76ff1..804c4bb 100644 --- a/the_app/models/shakespeare.py +++ b/the_app/models/shakespeare.py @@ -1,9 +1,9 @@ from sqlalchemy import (Column, ForeignKeyConstraint, Integer, PrimaryKeyConstraint, String, Table, Text, - UniqueConstraint) -from sqlalchemy.orm import declarative_base, relationship + UniqueConstraint, ForeignKey) +from sqlalchemy.orm import relationship -Base = declarative_base() +from the_app.models.base import Base metadata = Base.metadata