"""Initial database schema Revision ID: 001 Revises: Create Date: 2024-01-01 10:00:00.000000 """ from alembic import op import sqlalchemy as sa from sqlalchemy.types import TypeDecorator from pathlib import Path # revision identifiers, used by Alembic. revision = '001' down_revision = None branch_labels = None depends_on = None # Define the PathType here since it's needed for the migration class PathType(TypeDecorator): impl = sa.String cache_ok = True def process_bind_param(self, value, dialect): return None if value is None else str(value) def process_result_value(self, value, dialect): return None if value is None else Path(value) def upgrade() -> None: # This represents the initial schema from the original system # The tables (tags, genre, game, metadata, metadata_genres, metadata_tags) # already exist in the database, so this migration is just for tracking # If running on a fresh database, these would create the tables: # Create tags table op.create_table('tags', sa.Column('id', sa.Integer(), nullable=False), sa.Column('name', sa.String(length=30), nullable=False), sa.PrimaryKeyConstraint('id', name=op.f('pk_tags')) ) op.create_index('ix_tags_name', 'tags', ['name'], unique=True) # Create genre table op.create_table('genre', sa.Column('id', sa.Integer(), nullable=False), sa.Column('name', sa.String(length=30), nullable=False), sa.PrimaryKeyConstraint('id', name=op.f('pk_genre')) ) op.create_index('ix_genre_name', 'genre', ['name'], unique=True) # Create game table op.create_table('game', sa.Column('id', sa.Integer(), nullable=False), sa.Column('title', sa.String(length=66), nullable=False), sa.Column('path', PathType(), nullable=False), sa.PrimaryKeyConstraint('id', name=op.f('pk_game')), sa.UniqueConstraint('path', name=op.f('uq_game_path')) ) op.create_index('ix_game_title', 'game', ['title']) # Create metadata table op.create_table('metadata', sa.Column('id', sa.Integer(), nullable=False), sa.Column('game_id', sa.Integer(), nullable=False), sa.Column('title', sa.String(length=66), nullable=False), sa.Column('description', sa.String(), nullable=True), sa.Column('year', sa.Integer(), nullable=True), sa.Column('developer', sa.String(length=255), nullable=True), sa.Column('publisher', sa.String(length=255), nullable=True), sa.Column('players', sa.Integer(), nullable=True), sa.Column('cover_image', sa.String(), nullable=True), sa.Column('screenshot', sa.String(), nullable=True), sa.ForeignKeyConstraint(['game_id'], ['game.id'], name=op.f('fk_metadata_game_id_game'), ondelete='CASCADE'), sa.PrimaryKeyConstraint('id', name=op.f('pk_metadata')), sa.UniqueConstraint('game_id', name=op.f('uq_metadata_game_id')) ) # Create association tables op.create_table('metadata_genres', sa.Column('metadata_id', sa.Integer(), nullable=False), sa.Column('genre_id', sa.Integer(), nullable=False), sa.ForeignKeyConstraint(['genre_id'], ['genre.id'], name=op.f('fk_metadata_genres_genre_id_genre'), ondelete='CASCADE'), sa.ForeignKeyConstraint(['metadata_id'], ['metadata.id'], name=op.f('fk_metadata_genres_metadata_id_metadata'), ondelete='CASCADE'), sa.PrimaryKeyConstraint('metadata_id', 'genre_id', name=op.f('pk_metadata_genres')), sa.UniqueConstraint('metadata_id', 'genre_id', name=op.f('uq_metadata_genres_metadata_id')) ) op.create_table('metadata_tags', sa.Column('metadata_id', sa.Integer(), nullable=False), sa.Column('tag_id', sa.Integer(), nullable=False), sa.ForeignKeyConstraint(['metadata_id'], ['metadata.id'], name=op.f('fk_metadata_tags_metadata_id_metadata'), ondelete='CASCADE'), sa.ForeignKeyConstraint(['tag_id'], ['tags.id'], name=op.f('fk_metadata_tags_tag_id_tags'), ondelete='CASCADE'), sa.PrimaryKeyConstraint('metadata_id', 'tag_id', name=op.f('pk_metadata_tags')), sa.UniqueConstraint('metadata_id', 'tag_id', name=op.f('uq_metadata_tags_metadata_id')) ) def downgrade() -> None: op.drop_table('metadata_tags') op.drop_table('metadata_genres') op.drop_table('metadata') op.drop_table('game') op.drop_table('genre') op.drop_table('tags')