Skip to content
This repository was archived by the owner on Dec 11, 2021. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/lint-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ jobs:
PRE_COMMIT_HOME: ${{ github.workspace }}/.cache/pre-commit-cache

AUTH_TOKEN: ci-token
DATABASE_URL: postgres://pysite:pysite@postgres:5432/pysite
DATABASE_URL: postgresql+asyncpg://pysite:pysite@postgres:5432/pysite

# Via https://github.com/actions/example-services/blob/main/.github/workflows/postgres-service.yml
# services:
Expand Down
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,8 @@ If you want to propose new features for this API, please open an issue in the Is
The easiest way to set up a development environment is by using [`poetry`](https://python-poetry.org/). After installing `poetry`, simply run `poetry install` in the root of the cloned repository to set up a virtual environment with our development toolkit installed.

Another option is by using [Docker](https://www.docker.com/). After installing Docker on your machine, you should be able to run the API with `docker compose up`. For older versions of Docker, you may have to install `docker-compose` separately and run `docker-compose up` instead. This should spin up a container that automatically reloads the API if you change one of the files.

### Generating a migration file
With the project running in docker, open another terminal and run `poetry run task revision "Migration message here."`

This will create a migration file in the path `alembic/versions`. Make sure to check it over, and fix any linting issues.
42 changes: 28 additions & 14 deletions alembic/env.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import asyncio
from logging.config import fileConfig

from alembic import context
from sqlalchemy import engine_from_config
from sqlalchemy import pool
from sqlalchemy import engine_from_config, pool
from sqlalchemy.ext.asyncio import AsyncEngine
from sqlalchemy.ext.asyncio.engine import AsyncConnection

# This is a required step by Alembic to properly generate migrations
import api.core.database.models # noqa: F401
Expand Down Expand Up @@ -46,28 +48,40 @@ def run_migrations_offline() -> None:
context.run_migrations()


def run_migrations_online() -> None:
def do_run_migrations(connection: AsyncConnection):
"""Run all migrations on the given connection."""
context.configure(
connection=connection,
target_metadata=target_metadata,
compare_type=True,
compare_server_default=True
)

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.

"""
connectable = engine_from_config(
config.get_section(config.config_ini_section),
prefix="sqlalchemy.",
poolclass=pool.NullPool,
connectable = AsyncEngine(
engine_from_config(
config.get_section(config.config_ini_section),
prefix="sqlalchemy.",
poolclass=pool.NullPool,
future=True,
)
)

with connectable.connect() as connection:
context.configure(connection=connection, target_metadata=target_metadata)

with context.begin_transaction():
context.run_migrations()
async with connectable.connect() as connection:
await connection.run_sync(do_run_migrations)


if context.is_offline_mode():
run_migrations_offline()
else:
run_migrations_online()
asyncio.run(run_migrations_online())
5 changes: 3 additions & 2 deletions alembic/script.py.mako
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,9 @@ Revises: ${down_revision | comma,n}
Create Date: ${create_date}

"""
from alembic import op
import sqlalchemy as sa
from alembic import op
${imports if imports else ""}

# revision identifiers, used by Alembic.
revision = ${repr(up_revision)}
down_revision = ${repr(down_revision)}
Expand All @@ -17,8 +16,10 @@ depends_on = ${repr(depends_on)}


def upgrade():
"""Upgrade the connected DB to this revision."""
${upgrades if upgrades else "pass"}


def downgrade():
"""Downgrade the connected DB to the previous revision."""
${downgrades if downgrades else "pass"}
6 changes: 1 addition & 5 deletions api/core/database/models/api/bot/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@

from api.core.database import Base
from api.core.settings import settings
from .role import Role

engine = create_engine(settings.database_url)
SessionLocal = sessionmaker(bind=engine)
Expand Down Expand Up @@ -59,11 +58,8 @@ def validate_discriminator(

@validates("roles")
def validate_roles(self, _key: str, roles: list[int]) -> Union[list[int], NoReturn]:
"""Raise ValueError if the provided role(s) is negative or non-existent."""
session = SessionLocal()
"""Raise ValueError if the provided role(s) is negative."""
for role in roles:
if role < 0:
raise ValueError("Role IDs cannot be negative")
if not session.query(Role).filter_by(id=role).first():
raise ValueError(f"Role with ID {role} does not exist")
Comment thread
D0rs4n marked this conversation as resolved.
return roles
8 changes: 7 additions & 1 deletion api/core/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@
from pydantic import BaseSettings, PostgresDsn


class AsyncPostgresDsn(PostgresDsn):
"""Extension of Pydantic's PostgresDsn to only allow the "+asyncpg" schema."""

allowed_schemes = {"postgresql+asyncpg"}


class Settings(BaseSettings):
"""
A Settings class that will parse env variables.
Expand All @@ -27,7 +33,7 @@ class Settings(BaseSettings):
`pydantic.error_wrappers.ValidationError` exception.
"""

database_url: PostgresDsn
database_url: AsyncPostgresDsn
auth_token: str
commit_sha: str = "development"
DEBUG: bool = False
Expand Down
3 changes: 2 additions & 1 deletion docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ services:
tty: true
volumes:
- .:/app:ro
- ./alembic/versions:/app/alembic/versions
environment:
database_url: postgresql://pysite:pysite@postgres:5432/pysite
database_url: postgresql+asyncpg://pysite:pysite@postgres:5432/pysite
auth_token: "my_token"
debug: 1
Loading