Implement alemic database migrations

This commit is contained in:
Jeremy Zhang 2017-05-30 20:34:29 -07:00
parent 8cdb5c8ccf
commit b3051ab6bd
14 changed files with 468 additions and 0 deletions

1
.gitignore vendored
View File

@ -94,3 +94,4 @@ redislite.db
redislite.db.settings
webapp/tmp/*
!webapp/tmp/.gitinclude
alembic.ini

View File

@ -0,0 +1,68 @@
# A generic, single database configuration.
[alembic]
# path to migration scripts
script_location = alembic
# template used to generate migration files
# file_template = %%(rev)s_%%(slug)s
# max length of characters to apply to the
# "slug" field
#truncate_slug_length = 40
# set to 'true' to run the environment during
# the 'revision' command, regardless of autogenerate
# revision_environment = false
# set to 'true' to allow .pyc and .pyo files without
# a source .py file to be detected as revisions in the
# versions/ directory
# sourceless = false
# version location specification; this defaults
# to alembic/versions. When using multiple version
# directories, initial revisions must be specified with --version-path
# version_locations = %(here)s/bar %(here)s/bat alembic/versions
# the output encoding used when revision files
# are written from script.py.mako
# output_encoding = utf-8
sqlalchemy.url = driver://user:pass@localhost/dbname
# Logging configuration
[loggers]
keys = root,sqlalchemy,alembic
[handlers]
keys = console
[formatters]
keys = generic
[logger_root]
level = WARN
handlers = console
qualname =
[logger_sqlalchemy]
level = WARN
handlers =
qualname = sqlalchemy.engine
[logger_alembic]
level = INFO
handlers =
qualname = alembic
[handler_console]
class = StreamHandler
args = (sys.stderr,)
level = NOTSET
formatter = generic
[formatter_generic]
format = %(levelname)-5.5s [%(name)s] %(message)s
datefmt = %H:%M:%S

1
webapp/alembic/README Normal file
View File

@ -0,0 +1 @@
Generic single-database configuration.

76
webapp/alembic/env.py Normal file
View File

@ -0,0 +1,76 @@
from __future__ import with_statement
from alembic import context
from sqlalchemy import engine_from_config, pool
from logging.config import fileConfig
# this is the Alembic Config object, which provides
# access to the values within the .ini file in use.
config = context.config
# Interpret the config file for Python logging.
# This line sets up loggers basically.
fileConfig(config.config_file_name)
# add your model's MetaData object here
# for 'autogenerate' support
# from myapp import mymodel
# target_metadata = mymodel.Base.metadata
import os,sys,inspect
currentdir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
parentdir = os.path.dirname(currentdir)
sys.path.insert(0,parentdir)
from titanembeds import database
target_metadata = database.db.metadata
# other values from the config, defined by the needs of env.py,
# can be acquired:
# my_important_option = config.get_main_option("my_important_option")
# ... etc.
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 = config.get_main_option("sqlalchemy.url")
context.configure(
url=url, target_metadata=target_metadata, literal_binds=True)
with context.begin_transaction():
context.run_migrations()
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)
with connectable.connect() as connection:
context.configure(
connection=connection,
target_metadata=target_metadata
)
with context.begin_transaction():
context.run_migrations()
if context.is_offline_mode():
run_migrations_offline()
else:
run_migrations_online()

View File

@ -0,0 +1,24 @@
"""${message}
Revision ID: ${up_revision}
Revises: ${down_revision | comma,n}
Create Date: ${create_date}
"""
# revision identifiers, used by Alembic.
revision = ${repr(up_revision)}
down_revision = ${repr(down_revision)}
branch_labels = ${repr(branch_labels)}
depends_on = ${repr(depends_on)}
from alembic import op
import sqlalchemy as sa
${imports if imports else ""}
def upgrade():
${upgrades if upgrades else "pass"}
def downgrade():
${downgrades if downgrades else "pass"}

View File

@ -0,0 +1,30 @@
"""Create user css table
Revision ID: 32a4d2d7b85f
Revises: 6af1048a519e
Create Date: 2017-05-30 20:30:26.148504
"""
# revision identifiers, used by Alembic.
revision = '32a4d2d7b85f'
down_revision = '6af1048a519e'
branch_labels = None
depends_on = None
from alembic import op
import sqlalchemy as sa
def upgrade():
op.create_table(
'user_css',
sa.Column('id', sa.Integer, primary_key=True),
sa.Column('name', sa.String(255), nullable=False),
sa.Column('user_id', sa.String(255), nullable=False),
sa.Column('css', sa.Text()),
)
def downgrade():
op.drop_table('user_css')

View File

@ -0,0 +1,35 @@
"""Create unauthenticated bans table
Revision ID: 33c7a4b6c3e7
Revises: 77d1731aa4a5
Create Date: 2017-05-30 20:23:44.618429
"""
# revision identifiers, used by Alembic.
revision = '33c7a4b6c3e7'
down_revision = '77d1731aa4a5'
branch_labels = None
depends_on = None
from alembic import op
import sqlalchemy as sa
def upgrade():
op.create_table(
'unauthenticated_bans',
sa.Column('id', sa.Integer, primary_key=True),
sa.Column('guild_id', sa.String(255), nullable=False),
sa.Column('ip_address', sa.String(255), nullable=False),
sa.Column('last_username', sa.String(255), nullable=False),
sa.Column('last_discriminator', sa.Integer, nullable=False),
sa.Column('timestamp', sa.TIMESTAMP, nullable=False),
sa.Column('reason', sa.Text()),
sa.Column('lifter_id', sa.String(255)),
sa.Column('placer_id', sa.String(255), nullable=False),
)
def downgrade():
op.drop_table('unauthenticated_bans')

View File

@ -0,0 +1,30 @@
"""Create keyvalue table
Revision ID: 347cb289508e
Revises: a785afdbfa91
Create Date: 2017-05-30 20:16:22.543157
"""
# revision identifiers, used by Alembic.
revision = '347cb289508e'
down_revision = 'a785afdbfa91'
branch_labels = None
depends_on = None
from alembic import op
import sqlalchemy as sa
def upgrade():
op.create_table(
'keyvalue_properties',
sa.Column('id', sa.Integer, primary_key=True),
sa.Column('key', sa.String(255), nullable=False),
sa.Column('value', sa.Text()),
sa.Column('expiration', sa.TIMESTAMP),
)
def downgrade():
op.drop_table('keyvalue_properties')

View File

@ -0,0 +1,36 @@
"""Create guild_members table
Revision ID: 52e1d48f57d4
Revises: de55c5fc3c49
Create Date: 2017-05-30 20:01:55.380143
"""
# revision identifiers, used by Alembic.
revision = '52e1d48f57d4'
down_revision = 'de55c5fc3c49'
branch_labels = None
depends_on = None
from alembic import op
import sqlalchemy as sa
def upgrade():
op.create_table(
'guild_members',
sa.Column('id', sa.Integer, primary_key=True),
sa.Column('guild_id', sa.String(255), nullable=False),
sa.Column('user_id', sa.String(255), nullable=False),
sa.Column('username', sa.String(255), nullable=False),
sa.Column('discriminator', sa.Integer, nullable=False),
sa.Column('nickname', sa.String(255)),
sa.Column('avatar', sa.String(255)),
sa.Column('active', sa.Boolean(), nullable=False),
sa.Column('banned', sa.Boolean(), nullable=False),
sa.Column('roles', sa.Text(), nullable=False),
)
def downgrade():
op.drop_table('guild_members')

View File

@ -0,0 +1,34 @@
"""Create unauthenticated users table
Revision ID: 6af1048a519e
Revises: 33c7a4b6c3e7
Create Date: 2017-05-30 20:27:30.232927
"""
# revision identifiers, used by Alembic.
revision = '6af1048a519e'
down_revision = '33c7a4b6c3e7'
branch_labels = None
depends_on = None
from alembic import op
import sqlalchemy as sa
def upgrade():
op.create_table(
'unauthenticated_users',
sa.Column('id', sa.Integer, primary_key=True),
sa.Column('guild_id', sa.String(255), nullable=False),
sa.Column('username', sa.String(255), nullable=False),
sa.Column('discriminator', sa.Integer, nullable=False),
sa.Column('user_key', sa.Text(), nullable=False),
sa.Column('ip_address', sa.String(255), nullable=False),
sa.Column('last_timestamp', sa.TIMESTAMP, nullable=False),
sa.Column('revoked', sa.Boolean(), nullable=False),
)
def downgrade():
op.drop_table('unauthenticated_users')

View File

@ -0,0 +1,36 @@
"""Create messages table
Revision ID: 77d1731aa4a5
Revises: 347cb289508e
Create Date: 2017-05-30 20:19:04.713841
"""
# revision identifiers, used by Alembic.
revision = '77d1731aa4a5'
down_revision = '347cb289508e'
branch_labels = None
depends_on = None
from alembic import op
import sqlalchemy as sa
def upgrade():
op.create_table(
'messages',
sa.Column('id', sa.Integer, primary_key=True),
sa.Column('guild_id', sa.String(255), nullable=False),
sa.Column('channel_id', sa.String(255), nullable=False),
sa.Column('message_id', sa.String(255), nullable=False),
sa.Column('content', sa.Text(), nullable=False),
sa.Column('author', sa.Text(), nullable=False),
sa.Column('timestamp', sa.TIMESTAMP, nullable=False),
sa.Column('edited_timestamp', sa.TIMESTAMP),
sa.Column('mentions', sa.Text()),
sa.Column('attachments', sa.Text()),
)
def downgrade():
op.drop_table('messages')

View File

@ -0,0 +1,30 @@
"""create authenticated_users table
Revision ID: 906a48cc55d0
Revises:
Create Date: 2017-05-30 19:47:38.457143
"""
# revision identifiers, used by Alembic.
revision = '906a48cc55d0'
down_revision = None
branch_labels = None
depends_on = None
from alembic import op
import sqlalchemy as sa
def upgrade():
op.create_table(
'authenticated_users',
sa.Column('id', sa.Integer, primary_key=True),
sa.Column('guild_id', sa.String(255), nullable=False),
sa.Column('client_id', sa.String(255), nullable=False),
sa.Column('last_timestamp', sa.TIMESTAMP, nullable=False),
)
def downgrade():
op.drop_table('authenticated_users')

View File

@ -0,0 +1,38 @@
"""Create guilds table
Revision ID: a785afdbfa91
Revises: 52e1d48f57d4
Create Date: 2017-05-30 20:08:17.451959
"""
# revision identifiers, used by Alembic.
revision = 'a785afdbfa91'
down_revision = '52e1d48f57d4'
branch_labels = None
depends_on = None
from alembic import op
import sqlalchemy as sa
def upgrade():
op.create_table(
'guilds',
sa.Column('id', sa.Integer, primary_key=True),
sa.Column('guild_id', sa.String(255), nullable=False),
sa.Column('name', sa.String(255), nullable=False),
sa.Column('unauth_users', sa.Boolean(), nullable=False, default=1),
sa.Column('chat_links', sa.Boolean(), nullable=False, default=1),
sa.Column('bracket_links', sa.Boolean(), nullable=False, default=1),
sa.Column('mentions_limit', sa.Integer, nullable=False, default=11),
sa.Column('roles', sa.Text(), nullable=False),
sa.Column('channels', sa.Text(), nullable=False),
sa.Column('emojis', sa.Text(), nullable=False),
sa.Column('owner_id', sa.String(255), nullable=False),
sa.Column('icon', sa.String(255)),
)
def downgrade():
op.drop_table('guilds')

View File

@ -0,0 +1,29 @@
"""Create cosmetics table
Revision ID: de55c5fc3c49
Revises: 906a48cc55d0
Create Date: 2017-05-30 19:51:29.692001
"""
# revision identifiers, used by Alembic.
revision = 'de55c5fc3c49'
down_revision = '906a48cc55d0'
branch_labels = None
depends_on = None
from alembic import op
import sqlalchemy as sa
def upgrade():
op.create_table(
'cosmetics',
sa.Column('id', sa.Integer, primary_key=True),
sa.Column('user_id', sa.String(255), nullable=False),
sa.Column('css', sa.Boolean(), nullable=False),
)
def downgrade():
op.drop_table('cosmetics')