Skip to content

Commit 7157a51

Browse files
committed
Add alembic
1 parent 35cc2a3 commit 7157a51

11 files changed

+305
-2
lines changed

README.md

+23
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,26 @@ https://github.com/sdispater/poetry
1313
# running the bot
1414

1515
`poetry run start_bot`
16+
17+
# performing database migrations
18+
19+
## After making changes to the db schema, you should run
20+
21+
``` shell
22+
poetry run alembic revision --autogenerate -m "<description of schema change>"
23+
```
24+
25+
## When the db schema has been changed, you should run
26+
27+
``` shell
28+
poetry run alembic upgrade head
29+
```
30+
31+
## To check if the current db schema revision is the latest
32+
33+
``` shell
34+
poetry run alembic current
35+
```
36+
37+
- It should show a revision hash with `(head)` next to it if the db schema is up
38+
to data.

alembic.ini

+75
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
# A generic, single database configuration.
2+
3+
[alembic]
4+
# path to migration scripts
5+
script_location = alembic
6+
7+
# template used to generate migration files
8+
# file_template = %%(rev)s_%%(slug)s
9+
10+
# timezone to use when rendering the date
11+
# within the migration file as well as the filename.
12+
# string value is passed to dateutil.tz.gettz()
13+
# leave blank for localtime
14+
# timezone =
15+
16+
# max length of characters to apply to the
17+
# "slug" field
18+
#truncate_slug_length = 40
19+
20+
# set to 'true' to run the environment during
21+
# the 'revision' command, regardless of autogenerate
22+
# revision_environment = false
23+
24+
# set to 'true' to allow .pyc and .pyo files without
25+
# a source .py file to be detected as revisions in the
26+
# versions/ directory
27+
# sourceless = false
28+
29+
# version location specification; this defaults
30+
# to alembic/versions. When using multiple version
31+
# directories, initial revisions must be specified with --version-path
32+
# version_locations = %(here)s/bar %(here)s/bat alembic/versions
33+
34+
# the output encoding used when revision files
35+
# are written from script.py.mako
36+
# output_encoding = utf-8
37+
38+
# NOTE(ben): db url is configured from env vars
39+
# sqlalchemy.url = driver://user:pass@localhost/dbname
40+
41+
42+
# Logging configuration
43+
[loggers]
44+
keys = root,sqlalchemy,alembic
45+
46+
[handlers]
47+
keys = console
48+
49+
[formatters]
50+
keys = generic
51+
52+
[logger_root]
53+
level = WARN
54+
handlers = console
55+
qualname =
56+
57+
[logger_sqlalchemy]
58+
level = WARN
59+
handlers =
60+
qualname = sqlalchemy.engine
61+
62+
[logger_alembic]
63+
level = INFO
64+
handlers =
65+
qualname = alembic
66+
67+
[handler_console]
68+
class = StreamHandler
69+
args = (sys.stderr,)
70+
level = NOTSET
71+
formatter = generic
72+
73+
[formatter_generic]
74+
format = %(levelname)-5.5s [%(name)s] %(message)s
75+
datefmt = %H:%M:%S

alembic/README

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Generic single-database configuration.

alembic/env.py

+76
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
from __future__ import with_statement
2+
3+
import os
4+
import sys
5+
6+
sys.path.append(os.getcwd())
7+
8+
from logging.config import fileConfig
9+
10+
from dotenv import load_dotenv
11+
from sqlalchemy import engine_from_config, pool
12+
13+
from alembic import context
14+
from luhack_bot.db.models import db as target_metadata
15+
from luhack_bot.db.models import *
16+
17+
load_dotenv()
18+
19+
db_url = os.getenv("DB_URL")
20+
21+
# this is the Alembic Config object, which provides
22+
# access to the values within the .ini file in use.
23+
config = context.config
24+
25+
# Interpret the config file for Python logging.
26+
# This line sets up loggers basically.
27+
fileConfig(config.config_file_name)
28+
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():
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+
context.configure(url=db_url, target_metadata=target_metadata, literal_binds=True)
49+
50+
with context.begin_transaction():
51+
context.run_migrations()
52+
53+
54+
def run_migrations_online():
55+
"""Run migrations in 'online' mode.
56+
57+
In this scenario we need to create an Engine
58+
and associate a connection with the context.
59+
60+
"""
61+
alembic_config = config.get_section(config.config_ini_section)
62+
alembic_config["sqlalchemy.url"] = db_url
63+
connectable = engine_from_config(
64+
alembic_config, prefix="sqlalchemy.", poolclass=pool.NullPool
65+
)
66+
67+
with connectable.connect() as connection:
68+
context.configure(connection=connection, target_metadata=target_metadata)
69+
70+
with context.begin_transaction():
71+
context.run_migrations()
72+
73+
if context.is_offline_mode():
74+
run_migrations_offline()
75+
else:
76+
run_migrations_online()

alembic/script.py.mako

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
"""${message}
2+
3+
Revision ID: ${up_revision}
4+
Revises: ${down_revision | comma,n}
5+
Create Date: ${create_date}
6+
7+
"""
8+
from alembic import op
9+
import sqlalchemy as sa
10+
import sqlalchemy_utils
11+
${imports if imports else ""}
12+
13+
# revision identifiers, used by Alembic.
14+
revision = ${repr(up_revision)}
15+
down_revision = ${repr(down_revision)}
16+
branch_labels = ${repr(branch_labels)}
17+
depends_on = ${repr(depends_on)}
18+
19+
20+
def upgrade():
21+
${upgrades if upgrades else "pass"}
22+
23+
24+
def downgrade():
25+
${downgrades if downgrades else "pass"}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
"""Initial revision
2+
3+
Revision ID: 85a64ed7293f
4+
Revises:
5+
Create Date: 2019-03-14 17:30:16.457564
6+
7+
"""
8+
from alembic import op
9+
import sqlalchemy as sa
10+
import sqlalchemy_utils
11+
12+
13+
# revision identifiers, used by Alembic.
14+
revision = '85a64ed7293f'
15+
down_revision = None
16+
branch_labels = None
17+
depends_on = None
18+
19+
20+
def upgrade():
21+
# ### commands auto generated by Alembic - please adjust! ###
22+
op.create_table('users',
23+
sa.Column('discord_id', sa.BigInteger(), nullable=False),
24+
sa.Column('email', sqlalchemy_utils.types.encrypted.encrypted_type.EncryptedType(), nullable=False),
25+
sa.PrimaryKeyConstraint('discord_id')
26+
)
27+
# ### end Alembic commands ###
28+
29+
30+
def downgrade():
31+
# ### commands auto generated by Alembic - please adjust! ###
32+
op.drop_table('users')
33+
# ### end Alembic commands ###

luhack_bot/__init__.py

+2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
from textwrap import dedent
55
from cryptography.fernet import Fernet
66

7+
from luhack_bot import db
8+
79

810
def run():
911
"""Run the bot."""

luhack_bot/db/__init__.py

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from luhack_bot.db import helpers, models

luhack_bot/db/helpers.py

-1
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,3 @@
77

88
async def init_db():
99
await db.set_bind(db_url)
10-
await db.gino.create_all()

0 commit comments

Comments
 (0)