diff --git a/app/dependencies/database.py b/app/dependencies/database.py index e74af93..1525bfb 100644 --- a/app/dependencies/database.py +++ b/app/dependencies/database.py @@ -30,11 +30,6 @@ async def get_db(): yield session -async def create_tables(): - async with engine.begin() as conn: - await conn.run_sync(SQLModel.metadata.create_all) - - # Redis 依赖 def get_redis(): return redis_client diff --git a/main.py b/main.py index 8569afb..fe27c14 100644 --- a/main.py +++ b/main.py @@ -4,7 +4,7 @@ from contextlib import asynccontextmanager from datetime import datetime from app.config import settings -from app.dependencies.database import create_tables, engine, redis_client +from app.dependencies.database import engine, redis_client from app.dependencies.fetcher import get_fetcher from app.dependencies.scheduler import init_scheduler, stop_scheduler from app.router import ( @@ -21,7 +21,6 @@ from fastapi import FastAPI @asynccontextmanager async def lifespan(app: FastAPI): # on startup - await create_tables() await get_fetcher() # 初始化 fetcher init_scheduler() await daily_challenge_job() diff --git a/migrations/versions/.gitkeep b/migrations/versions/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/migrations/versions/1178d0758ebf_beatmapset_support_favourite_count.py b/migrations/versions/1178d0758ebf_beatmapset_support_favourite_count.py deleted file mode 100644 index 84bae15..0000000 --- a/migrations/versions/1178d0758ebf_beatmapset_support_favourite_count.py +++ /dev/null @@ -1,40 +0,0 @@ -"""beatmapset: support favourite count - -Revision ID: 1178d0758ebf -Revises: -Create Date: 2025-08-01 04:05:09.882800 - -""" - -from __future__ import annotations - -from collections.abc import Sequence - -from alembic import op -import sqlalchemy as sa -from sqlalchemy.dialects import mysql - -# revision identifiers, used by Alembic. -revision: str = "1178d0758ebf" -down_revision: str | Sequence[str] | None = None -branch_labels: str | Sequence[str] | None = None -depends_on: str | Sequence[str] | None = None - - -def upgrade() -> None: - """Upgrade schema.""" - # ### commands auto generated by Alembic - please adjust! ### - op.drop_column("beatmapsets", "favourite_count") - # ### end Alembic commands ### - - -def downgrade() -> None: - """Downgrade schema.""" - # ### commands auto generated by Alembic - please adjust! ### - op.add_column( - "beatmapsets", - sa.Column( - "favourite_count", mysql.INTEGER(), autoincrement=False, nullable=False - ), - ) - # ### end Alembic commands ### diff --git a/migrations/versions/58a11441d302_relationship_fix_unique_relationship.py b/migrations/versions/58a11441d302_relationship_fix_unique_relationship.py deleted file mode 100644 index e383621..0000000 --- a/migrations/versions/58a11441d302_relationship_fix_unique_relationship.py +++ /dev/null @@ -1,54 +0,0 @@ -"""relationship: fix unique relationship - -Revision ID: 58a11441d302 -Revises: 1178d0758ebf -Create Date: 2025-08-01 04:23:02.498166 - -""" - -from __future__ import annotations - -from collections.abc import Sequence - -from alembic import op -import sqlalchemy as sa -from sqlalchemy.dialects import mysql - -# revision identifiers, used by Alembic. -revision: str = "58a11441d302" -down_revision: str | Sequence[str] | None = "1178d0758ebf" -branch_labels: str | Sequence[str] | None = None -depends_on: str | Sequence[str] | None = None - - -def upgrade() -> None: - """Upgrade schema.""" - # ### commands auto generated by Alembic - please adjust! ### - op.add_column( - "relationship", - sa.Column("id", sa.BigInteger(), autoincrement=True, nullable=False), - ) - op.drop_constraint("PRIMARY", "relationship", type_="primary") - op.create_primary_key("pk_relationship", "relationship", ["id"]) - op.alter_column( - "relationship", "user_id", existing_type=mysql.BIGINT(), nullable=True - ) - op.alter_column( - "relationship", "target_id", existing_type=mysql.BIGINT(), nullable=True - ) - # ### end Alembic commands ### - - -def downgrade() -> None: - """Downgrade schema.""" - # ### commands auto generated by Alembic - please adjust! ### - op.drop_constraint("pk_relationship", "relationship", type_="primary") - op.create_primary_key("PRIMARY", "relationship", ["user_id", "target_id"]) - op.alter_column( - "relationship", "target_id", existing_type=mysql.BIGINT(), nullable=False - ) - op.alter_column( - "relationship", "user_id", existing_type=mysql.BIGINT(), nullable=False - ) - op.drop_column("relationship", "id") - # ### end Alembic commands ### diff --git a/migrations/versions/d0c1b2cefe91_playlist_index_playlist_id.py b/migrations/versions/d0c1b2cefe91_playlist_index_playlist_id.py deleted file mode 100644 index 74f2e56..0000000 --- a/migrations/versions/d0c1b2cefe91_playlist_index_playlist_id.py +++ /dev/null @@ -1,89 +0,0 @@ -"""playlist: index playlist id - -Revision ID: d0c1b2cefe91 -Revises: 58a11441d302 -Create Date: 2025-08-06 06:02:10.512616 - -""" - -from __future__ import annotations - -from collections.abc import Sequence - -from alembic import op -import sqlalchemy as sa - -# revision identifiers, used by Alembic. -revision: str = "d0c1b2cefe91" -down_revision: str | Sequence[str] | None = "58a11441d302" -branch_labels: str | Sequence[str] | None = None -depends_on: str | Sequence[str] | None = None - - -def upgrade() -> None: - """Upgrade schema.""" - # ### commands auto generated by Alembic - please adjust! ### - op.create_index( - op.f("ix_room_playlists_id"), "room_playlists", ["id"], unique=False - ) - op.create_table( - "playlist_best_scores", - sa.Column("user_id", sa.BigInteger(), nullable=True), - sa.Column("score_id", sa.BigInteger(), nullable=False), - sa.Column("room_id", sa.Integer(), nullable=False), - sa.Column("playlist_id", sa.Integer(), nullable=False), - sa.Column("total_score", sa.BigInteger(), nullable=True), - sa.ForeignKeyConstraint( - ["playlist_id"], - ["room_playlists.id"], - ), - sa.ForeignKeyConstraint( - ["room_id"], - ["rooms.id"], - ), - sa.ForeignKeyConstraint( - ["score_id"], - ["scores.id"], - ), - sa.ForeignKeyConstraint( - ["user_id"], - ["lazer_users.id"], - ), - sa.PrimaryKeyConstraint("score_id"), - ) - op.create_index( - op.f("ix_playlist_best_scores_playlist_id"), - "playlist_best_scores", - ["playlist_id"], - unique=False, - ) - op.create_index( - op.f("ix_playlist_best_scores_room_id"), - "playlist_best_scores", - ["room_id"], - unique=False, - ) - op.create_index( - op.f("ix_playlist_best_scores_user_id"), - "playlist_best_scores", - ["user_id"], - unique=False, - ) - # ### end Alembic commands ### - - -def downgrade() -> None: - """Downgrade schema.""" - # ### commands auto generated by Alembic - please adjust! ### - op.drop_index( - op.f("ix_playlist_best_scores_user_id"), table_name="playlist_best_scores" - ) - op.drop_index( - op.f("ix_playlist_best_scores_room_id"), table_name="playlist_best_scores" - ) - op.drop_index( - op.f("ix_playlist_best_scores_playlist_id"), table_name="playlist_best_scores" - ) - op.drop_table("playlist_best_scores") - op.drop_index(op.f("ix_room_playlists_id"), table_name="room_playlists") - # ### end Alembic commands ### diff --git a/migrations/versions/fdb3822a30ba_init.py b/migrations/versions/fdb3822a30ba_init.py new file mode 100644 index 0000000..55ace06 --- /dev/null +++ b/migrations/versions/fdb3822a30ba_init.py @@ -0,0 +1,1069 @@ +"""init + +Revision ID: fdb3822a30ba +Revises: +Create Date: 2025-08-10 04:30:58.443568 + +""" + +from __future__ import annotations + +from collections.abc import Sequence + +from alembic import op +import sqlalchemy as sa +import sqlmodel + +# revision identifiers, used by Alembic. +revision: str = "fdb3822a30ba" +down_revision: str | Sequence[str] | None = None +branch_labels: str | Sequence[str] | None = None +depends_on: str | Sequence[str] | None = None + + +def upgrade() -> None: + """Upgrade schema.""" + # ### commands auto generated by Alembic - please adjust! ### + op.create_table( + "beatmapsets", + sa.Column("artist", sqlmodel.sql.sqltypes.AutoString(), nullable=False), + sa.Column("artist_unicode", sqlmodel.sql.sqltypes.AutoString(), nullable=False), + sa.Column("covers", sa.JSON(), nullable=True), + sa.Column("creator", sqlmodel.sql.sqltypes.AutoString(), nullable=False), + sa.Column("nsfw", sa.Boolean(), nullable=False), + sa.Column("play_count", sa.Integer(), nullable=False), + sa.Column("preview_url", sqlmodel.sql.sqltypes.AutoString(), nullable=False), + sa.Column("source", sqlmodel.sql.sqltypes.AutoString(), nullable=False), + sa.Column("spotlight", sa.Boolean(), nullable=False), + sa.Column("title", sqlmodel.sql.sqltypes.AutoString(), nullable=False), + sa.Column("title_unicode", sqlmodel.sql.sqltypes.AutoString(), nullable=False), + sa.Column("user_id", sa.Integer(), nullable=False), + sa.Column("video", sa.Boolean(), nullable=False), + sa.Column("current_nominations", sa.JSON(), nullable=True), + sa.Column("description", sa.JSON(), nullable=True), + sa.Column("pack_tags", sa.JSON(), nullable=True), + sa.Column("ratings", sa.JSON(), nullable=True), + sa.Column("track_id", sa.Integer(), nullable=True), + sa.Column("bpm", sa.Float(), nullable=False), + sa.Column("can_be_hyped", sa.Boolean(), nullable=False), + sa.Column("discussion_locked", sa.Boolean(), nullable=False), + sa.Column("last_updated", sa.DateTime(), nullable=True), + sa.Column("ranked_date", sa.DateTime(), nullable=True), + sa.Column("storyboard", sa.Boolean(), nullable=False), + sa.Column("submitted_date", sa.DateTime(), nullable=True), + sa.Column("tags", sa.Text(), nullable=True), + sa.Column("id", sa.Integer(), nullable=False), + sa.Column( + "beatmap_status", + sa.Enum( + "GRAVEYARD", + "WIP", + "PENDING", + "RANKED", + "APPROVED", + "QUALIFIED", + "LOVED", + name="beatmaprankstatus", + ), + nullable=False, + ), + sa.Column( + "beatmap_genre", + sa.Enum( + "ANY", + "UNSPECIFIED", + "VIDEO_GAME", + "ANIME", + "ROCK", + "POP", + "OTHER", + "NOVELTY", + "HIP_HOP", + "ELECTRONIC", + "METAL", + "CLASSICAL", + "FOLK", + "JAZZ", + name="genre", + ), + nullable=False, + ), + sa.Column( + "beatmap_language", + sa.Enum( + "ANY", + "UNSPECIFIED", + "ENGLISH", + "JAPANESE", + "CHINESE", + "INSTRUMENTAL", + "KOREAN", + "FRENCH", + "GERMAN", + "SWEDISH", + "ITALIAN", + "SPANISH", + "RUSSIAN", + "POLISH", + "OTHER", + name="language", + ), + nullable=False, + ), + sa.Column("nominations_required", sa.Integer(), nullable=False), + sa.Column("nominations_current", sa.Integer(), nullable=False), + sa.Column("hype_current", sa.Integer(), nullable=False), + sa.Column("hype_required", sa.Integer(), nullable=False), + sa.Column( + "availability_info", sqlmodel.sql.sqltypes.AutoString(), nullable=True + ), + sa.Column("download_disabled", sa.Boolean(), nullable=False), + sa.PrimaryKeyConstraint("id"), + ) + op.create_index( + op.f("ix_beatmapsets_artist"), "beatmapsets", ["artist"], unique=False + ) + op.create_index( + op.f("ix_beatmapsets_artist_unicode"), + "beatmapsets", + ["artist_unicode"], + unique=False, + ) + op.create_index(op.f("ix_beatmapsets_id"), "beatmapsets", ["id"], unique=False) + op.create_table( + "lazer_users", + sa.Column("avatar_url", sqlmodel.sql.sqltypes.AutoString(), nullable=False), + sa.Column( + "country_code", sqlmodel.sql.sqltypes.AutoString(length=2), nullable=False + ), + sa.Column("is_active", sa.Boolean(), nullable=False), + sa.Column("is_bot", sa.Boolean(), nullable=False), + sa.Column("is_supporter", sa.Boolean(), nullable=False), + sa.Column("last_visit", sa.DateTime(timezone=True), nullable=True), + sa.Column("pm_friends_only", sa.Boolean(), nullable=False), + sa.Column("profile_colour", sqlmodel.sql.sqltypes.AutoString(), nullable=True), + sa.Column( + "username", sqlmodel.sql.sqltypes.AutoString(length=32), nullable=False + ), + sa.Column("page", sa.JSON(), nullable=True), + sa.Column("previous_usernames", sa.JSON(), nullable=True), + sa.Column("support_level", sa.Integer(), nullable=False), + sa.Column("badges", sa.JSON(), nullable=True), + sa.Column("is_restricted", sa.Boolean(), nullable=False), + sa.Column("cover", sa.JSON(), nullable=True), + sa.Column("beatmap_playcounts_count", sa.Integer(), nullable=False), + sa.Column( + "playmode", + sa.Enum("OSU", "TAIKO", "FRUITS", "MANIA", name="gamemode"), + nullable=False, + ), + sa.Column("discord", sqlmodel.sql.sqltypes.AutoString(), nullable=True), + sa.Column("has_supported", sa.Boolean(), nullable=False), + sa.Column("interests", sqlmodel.sql.sqltypes.AutoString(), nullable=True), + sa.Column("join_date", sa.DateTime(), nullable=False), + sa.Column("location", sqlmodel.sql.sqltypes.AutoString(), nullable=True), + sa.Column("max_blocks", sa.Integer(), nullable=False), + sa.Column("max_friends", sa.Integer(), nullable=False), + sa.Column("occupation", sqlmodel.sql.sqltypes.AutoString(), nullable=True), + sa.Column("playstyle", sa.JSON(), nullable=True), + sa.Column("profile_hue", sa.Integer(), nullable=True), + sa.Column("profile_order", sa.JSON(), nullable=True), + sa.Column("title", sqlmodel.sql.sqltypes.AutoString(), nullable=True), + sa.Column("title_url", sqlmodel.sql.sqltypes.AutoString(), nullable=True), + sa.Column("twitter", sqlmodel.sql.sqltypes.AutoString(), nullable=True), + sa.Column("website", sqlmodel.sql.sqltypes.AutoString(), nullable=True), + sa.Column("comments_count", sa.Integer(), nullable=False), + sa.Column("post_count", sa.Integer(), nullable=False), + sa.Column("is_admin", sa.Boolean(), nullable=False), + sa.Column("is_gmt", sa.Boolean(), nullable=False), + sa.Column("is_qat", sa.Boolean(), nullable=False), + sa.Column("is_bng", sa.Boolean(), nullable=False), + sa.Column("id", sa.BigInteger(), autoincrement=True, nullable=False), + sa.Column( + "email", sqlmodel.sql.sqltypes.AutoString(length=254), nullable=False + ), + sa.Column("priv", sa.Integer(), nullable=False), + sa.Column( + "pw_bcrypt", sqlmodel.sql.sqltypes.AutoString(length=60), nullable=False + ), + sa.Column("silence_end_at", sa.DateTime(timezone=True), nullable=True), + sa.Column("donor_end_at", sa.DateTime(timezone=True), nullable=True), + sa.PrimaryKeyConstraint("id"), + ) + op.create_index( + op.f("ix_lazer_users_country_code"), + "lazer_users", + ["country_code"], + unique=False, + ) + op.create_index(op.f("ix_lazer_users_email"), "lazer_users", ["email"], unique=True) + op.create_index(op.f("ix_lazer_users_id"), "lazer_users", ["id"], unique=False) + op.create_index( + op.f("ix_lazer_users_username"), "lazer_users", ["username"], unique=True + ) + op.create_table( + "teams", + sa.Column("id", sa.Integer(), nullable=False), + sa.Column("name", sqlmodel.sql.sqltypes.AutoString(length=100), nullable=False), + sa.Column( + "short_name", sqlmodel.sql.sqltypes.AutoString(length=10), nullable=False + ), + sa.Column( + "flag_url", sqlmodel.sql.sqltypes.AutoString(length=500), nullable=True + ), + sa.Column("created_at", sa.DateTime(), nullable=True), + sa.PrimaryKeyConstraint("id"), + ) + op.create_index(op.f("ix_teams_id"), "teams", ["id"], unique=False) + op.create_table( + "beatmaps", + sa.Column("url", sqlmodel.sql.sqltypes.AutoString(), nullable=False), + sa.Column( + "mode", + sa.Enum("OSU", "TAIKO", "FRUITS", "MANIA", name="gamemode"), + nullable=False, + ), + sa.Column("difficulty_rating", sa.Float(), nullable=False), + sa.Column("total_length", sa.Integer(), nullable=False), + sa.Column("user_id", sa.Integer(), nullable=False), + sa.Column("version", sqlmodel.sql.sqltypes.AutoString(), nullable=False), + sa.Column("checksum", sa.VARCHAR(length=32), nullable=True), + sa.Column("current_user_playcount", sa.Integer(), nullable=False), + sa.Column("max_combo", sa.Integer(), nullable=False), + sa.Column("ar", sa.Float(), nullable=False), + sa.Column("cs", sa.Float(), nullable=False), + sa.Column("drain", sa.Float(), nullable=False), + sa.Column("accuracy", sa.Float(), nullable=False), + sa.Column("bpm", sa.Float(), nullable=False), + sa.Column("count_circles", sa.Integer(), nullable=False), + sa.Column("count_sliders", sa.Integer(), nullable=False), + sa.Column("count_spinners", sa.Integer(), nullable=False), + sa.Column("deleted_at", sa.DateTime(), nullable=True), + sa.Column("hit_length", sa.Integer(), nullable=False), + sa.Column("last_updated", sa.DateTime(), nullable=True), + sa.Column("id", sa.Integer(), nullable=False), + sa.Column("beatmapset_id", sa.Integer(), nullable=False), + sa.Column( + "beatmap_status", + sa.Enum( + "GRAVEYARD", + "WIP", + "PENDING", + "RANKED", + "APPROVED", + "QUALIFIED", + "LOVED", + name="beatmaprankstatus", + ), + nullable=False, + ), + sa.ForeignKeyConstraint( + ["beatmapset_id"], + ["beatmapsets.id"], + ), + sa.PrimaryKeyConstraint("id"), + ) + op.create_index( + op.f("ix_beatmaps_beatmapset_id"), "beatmaps", ["beatmapset_id"], unique=False + ) + op.create_index( + op.f("ix_beatmaps_checksum"), "beatmaps", ["checksum"], unique=False + ) + op.create_index(op.f("ix_beatmaps_id"), "beatmaps", ["id"], unique=False) + op.create_table( + "daily_challenge_stats", + sa.Column("daily_streak_best", sa.Integer(), nullable=False), + sa.Column("daily_streak_current", sa.Integer(), nullable=False), + sa.Column("last_update", sa.DateTime(), nullable=True), + sa.Column("last_weekly_streak", sa.DateTime(), nullable=True), + sa.Column("playcount", sa.Integer(), nullable=False), + sa.Column("top_10p_placements", sa.Integer(), nullable=False), + sa.Column("top_50p_placements", sa.Integer(), nullable=False), + sa.Column("weekly_streak_best", sa.Integer(), nullable=False), + sa.Column("weekly_streak_current", sa.Integer(), nullable=False), + sa.Column("user_id", sa.BigInteger(), nullable=False), + sa.ForeignKeyConstraint( + ["user_id"], + ["lazer_users.id"], + ), + sa.PrimaryKeyConstraint("user_id"), + ) + op.create_index( + op.f("ix_daily_challenge_stats_user_id"), + "daily_challenge_stats", + ["user_id"], + unique=True, + ) + op.create_table( + "favourite_beatmapset", + sa.Column("id", sa.BigInteger(), autoincrement=True, nullable=False), + sa.Column("user_id", sa.BigInteger(), nullable=True), + sa.Column("beatmapset_id", sa.Integer(), nullable=True), + sa.Column("date", sa.DateTime(), nullable=True), + sa.ForeignKeyConstraint( + ["beatmapset_id"], + ["beatmapsets.id"], + ), + sa.ForeignKeyConstraint( + ["user_id"], + ["lazer_users.id"], + ), + sa.PrimaryKeyConstraint("id"), + ) + op.create_index( + op.f("ix_favourite_beatmapset_beatmapset_id"), + "favourite_beatmapset", + ["beatmapset_id"], + unique=False, + ) + op.create_index( + op.f("ix_favourite_beatmapset_user_id"), + "favourite_beatmapset", + ["user_id"], + unique=False, + ) + op.create_table( + "lazer_user_achievements", + sa.Column("achievement_id", sa.Integer(), nullable=False), + sa.Column("achieved_at", sa.DateTime(timezone=True), nullable=True), + sa.Column("id", sa.Integer(), nullable=False), + sa.Column("user_id", sa.BigInteger(), nullable=True), + sa.ForeignKeyConstraint( + ["user_id"], + ["lazer_users.id"], + ), + sa.PrimaryKeyConstraint("achievement_id", "id"), + ) + op.create_index( + op.f("ix_lazer_user_achievements_id"), + "lazer_user_achievements", + ["id"], + unique=False, + ) + op.create_table( + "lazer_user_statistics", + sa.Column( + "mode", + sa.Enum("OSU", "TAIKO", "FRUITS", "MANIA", name="gamemode"), + nullable=False, + ), + sa.Column("count_100", sa.BigInteger(), nullable=True), + sa.Column("count_300", sa.BigInteger(), nullable=True), + sa.Column("count_50", sa.BigInteger(), nullable=True), + sa.Column("count_miss", sa.BigInteger(), nullable=True), + sa.Column("global_rank", sa.Integer(), nullable=True), + sa.Column("country_rank", sa.Integer(), nullable=True), + sa.Column("pp", sa.Float(), nullable=False), + sa.Column("ranked_score", sa.Integer(), nullable=False), + sa.Column("hit_accuracy", sa.Float(), nullable=False), + sa.Column("total_score", sa.BigInteger(), nullable=True), + sa.Column("total_hits", sa.BigInteger(), nullable=True), + sa.Column("maximum_combo", sa.Integer(), nullable=False), + sa.Column("play_count", sa.Integer(), nullable=False), + sa.Column("play_time", sa.BigInteger(), nullable=True), + sa.Column("replays_watched_by_others", sa.Integer(), nullable=False), + sa.Column("is_ranked", sa.Boolean(), nullable=False), + sa.Column("id", sa.Integer(), nullable=False), + sa.Column("user_id", sa.BigInteger(), nullable=True), + sa.Column("grade_ss", sa.Integer(), nullable=False), + sa.Column("grade_ssh", sa.Integer(), nullable=False), + sa.Column("grade_s", sa.Integer(), nullable=False), + sa.Column("grade_sh", sa.Integer(), nullable=False), + sa.Column("grade_a", sa.Integer(), nullable=False), + sa.Column("level_current", sa.Integer(), nullable=False), + sa.Column("level_progress", sa.Integer(), nullable=False), + sa.ForeignKeyConstraint( + ["user_id"], + ["lazer_users.id"], + ), + sa.PrimaryKeyConstraint("id"), + ) + op.create_index( + op.f("ix_lazer_user_statistics_user_id"), + "lazer_user_statistics", + ["user_id"], + unique=False, + ) + op.create_table( + "monthly_playcounts", + sa.Column("id", sa.BigInteger(), autoincrement=True, nullable=False), + sa.Column("user_id", sa.BigInteger(), nullable=True), + sa.Column("year", sa.Integer(), nullable=False), + sa.Column("month", sa.Integer(), nullable=False), + sa.Column("playcount", sa.Integer(), nullable=False), + sa.ForeignKeyConstraint( + ["user_id"], + ["lazer_users.id"], + ), + sa.PrimaryKeyConstraint("id"), + ) + op.create_index( + op.f("ix_monthly_playcounts_month"), + "monthly_playcounts", + ["month"], + unique=False, + ) + op.create_index( + op.f("ix_monthly_playcounts_user_id"), + "monthly_playcounts", + ["user_id"], + unique=False, + ) + op.create_index( + op.f("ix_monthly_playcounts_year"), "monthly_playcounts", ["year"], unique=False + ) + op.create_table( + "oauth_tokens", + sa.Column("id", sa.Integer(), nullable=False), + sa.Column("user_id", sa.BigInteger(), nullable=True), + sa.Column( + "access_token", sqlmodel.sql.sqltypes.AutoString(length=500), nullable=False + ), + sa.Column( + "refresh_token", + sqlmodel.sql.sqltypes.AutoString(length=500), + nullable=False, + ), + sa.Column( + "token_type", sqlmodel.sql.sqltypes.AutoString(length=20), nullable=False + ), + sa.Column( + "scope", sqlmodel.sql.sqltypes.AutoString(length=100), nullable=False + ), + sa.Column("expires_at", sa.DateTime(), nullable=True), + sa.Column("created_at", sa.DateTime(), nullable=True), + sa.ForeignKeyConstraint( + ["user_id"], + ["lazer_users.id"], + ), + sa.PrimaryKeyConstraint("id"), + sa.UniqueConstraint("access_token"), + sa.UniqueConstraint("refresh_token"), + ) + op.create_index(op.f("ix_oauth_tokens_id"), "oauth_tokens", ["id"], unique=False) + op.create_index( + op.f("ix_oauth_tokens_user_id"), "oauth_tokens", ["user_id"], unique=False + ) + op.create_table( + "relationship", + sa.Column("id", sa.BigInteger(), autoincrement=True, nullable=False), + sa.Column("user_id", sa.BigInteger(), nullable=True), + sa.Column("target_id", sa.BigInteger(), nullable=True), + sa.Column( + "type", sa.Enum("FOLLOW", "BLOCK", name="relationshiptype"), nullable=False + ), + sa.ForeignKeyConstraint( + ["target_id"], + ["lazer_users.id"], + ), + sa.ForeignKeyConstraint( + ["user_id"], + ["lazer_users.id"], + ), + sa.PrimaryKeyConstraint("id"), + ) + op.create_index( + op.f("ix_relationship_target_id"), "relationship", ["target_id"], unique=False + ) + op.create_index( + op.f("ix_relationship_user_id"), "relationship", ["user_id"], unique=False + ) + op.create_table( + "rooms", + sa.Column("name", sqlmodel.sql.sqltypes.AutoString(), nullable=False), + sa.Column( + "category", + sa.Enum( + "NORMAL", + "SPOTLIGHT", + "FEATURED_ARTIST", + "DAILY_CHALLENGE", + "REALTIME", + name="roomcategory", + ), + nullable=False, + ), + sa.Column("duration", sa.Integer(), nullable=True), + sa.Column("starts_at", sa.DateTime(timezone=True), nullable=True), + sa.Column("ends_at", sa.DateTime(timezone=True), nullable=True), + sa.Column("participant_count", sa.Integer(), nullable=False), + sa.Column("max_attempts", sa.Integer(), nullable=True), + sa.Column( + "type", + sa.Enum("PLAYLISTS", "HEAD_TO_HEAD", "TEAM_VERSUS", name="matchtype"), + nullable=False, + ), + sa.Column( + "queue_mode", + sa.Enum( + "HOST_ONLY", "ALL_PLAYERS", "ALL_PLAYERS_ROUND_ROBIN", name="queuemode" + ), + nullable=False, + ), + sa.Column("auto_skip", sa.Boolean(), nullable=False), + sa.Column("auto_start_duration", sa.Integer(), nullable=False), + sa.Column( + "status", sa.Enum("IDLE", "PLAYING", name="roomstatus"), nullable=False + ), + sa.Column("id", sa.Integer(), nullable=False), + sa.Column("host_id", sa.BigInteger(), nullable=True), + sa.ForeignKeyConstraint( + ["host_id"], + ["lazer_users.id"], + ), + sa.PrimaryKeyConstraint("id"), + ) + op.create_index(op.f("ix_rooms_category"), "rooms", ["category"], unique=False) + op.create_index(op.f("ix_rooms_host_id"), "rooms", ["host_id"], unique=False) + op.create_index(op.f("ix_rooms_id"), "rooms", ["id"], unique=False) + op.create_index(op.f("ix_rooms_name"), "rooms", ["name"], unique=False) + op.create_table( + "team_members", + sa.Column("id", sa.Integer(), nullable=False), + sa.Column("user_id", sa.BigInteger(), nullable=True), + sa.Column("team_id", sa.Integer(), nullable=False), + sa.Column("joined_at", sa.DateTime(), nullable=True), + sa.ForeignKeyConstraint( + ["team_id"], + ["teams.id"], + ), + sa.ForeignKeyConstraint( + ["user_id"], + ["lazer_users.id"], + ), + sa.PrimaryKeyConstraint("id"), + ) + op.create_index(op.f("ix_team_members_id"), "team_members", ["id"], unique=False) + op.create_table( + "user_account_history", + sa.Column("description", sqlmodel.sql.sqltypes.AutoString(), nullable=True), + sa.Column("length", sa.Integer(), nullable=False), + sa.Column("permanent", sa.Boolean(), nullable=False), + sa.Column("timestamp", sa.DateTime(), nullable=False), + sa.Column( + "type", + sa.Enum( + "NOTE", + "RESTRICTION", + "SLIENCE", + "TOURNAMENT_BAN", + name="useraccounthistorytype", + ), + nullable=False, + ), + sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), + sa.Column("user_id", sa.BigInteger(), nullable=True), + sa.ForeignKeyConstraint( + ["user_id"], + ["lazer_users.id"], + ), + sa.PrimaryKeyConstraint("id"), + ) + op.create_index( + op.f("ix_user_account_history_id"), "user_account_history", ["id"], unique=False + ) + op.create_index( + op.f("ix_user_account_history_user_id"), + "user_account_history", + ["user_id"], + unique=False, + ) + op.create_table( + "beatmap_playcounts", + sa.Column("id", sa.BigInteger(), autoincrement=True, nullable=False), + sa.Column("user_id", sa.BigInteger(), nullable=True), + sa.Column("beatmap_id", sa.Integer(), nullable=False), + sa.Column("playcount", sa.Integer(), nullable=False), + sa.ForeignKeyConstraint( + ["beatmap_id"], + ["beatmaps.id"], + ), + sa.ForeignKeyConstraint( + ["user_id"], + ["lazer_users.id"], + ), + sa.PrimaryKeyConstraint("id"), + ) + op.create_index( + op.f("ix_beatmap_playcounts_beatmap_id"), + "beatmap_playcounts", + ["beatmap_id"], + unique=False, + ) + op.create_index( + op.f("ix_beatmap_playcounts_user_id"), + "beatmap_playcounts", + ["user_id"], + unique=False, + ) + op.create_table( + "item_attempts_count", + sa.Column("room_id", sa.Integer(), nullable=False), + sa.Column("attempts", sa.Integer(), nullable=False), + sa.Column("completed", sa.Integer(), nullable=False), + sa.Column("user_id", sa.BigInteger(), nullable=True), + sa.Column("accuracy", sa.Float(), nullable=False), + sa.Column("pp", sa.Float(), nullable=False), + sa.Column("total_score", sa.Integer(), nullable=False), + sa.Column("id", sa.Integer(), nullable=False), + sa.ForeignKeyConstraint( + ["room_id"], + ["rooms.id"], + ), + sa.ForeignKeyConstraint( + ["user_id"], + ["lazer_users.id"], + ), + sa.PrimaryKeyConstraint("id"), + ) + op.create_index( + op.f("ix_item_attempts_count_room_id"), + "item_attempts_count", + ["room_id"], + unique=False, + ) + op.create_index( + op.f("ix_item_attempts_count_user_id"), + "item_attempts_count", + ["user_id"], + unique=False, + ) + op.create_table( + "multiplayer_events", + sa.Column("playlist_item_id", sa.Integer(), nullable=True), + sa.Column("user_id", sa.BigInteger(), nullable=True), + sa.Column("created_at", sa.DateTime(timezone=True), nullable=True), + sa.Column("event_type", sqlmodel.sql.sqltypes.AutoString(), nullable=False), + sa.Column("id", sa.BigInteger(), autoincrement=True, nullable=False), + sa.Column("room_id", sa.Integer(), nullable=False), + sa.Column("updated_at", sa.DateTime(timezone=True), nullable=True), + sa.Column("event_detail", sa.JSON(), nullable=True), + sa.ForeignKeyConstraint( + ["room_id"], + ["rooms.id"], + ), + sa.ForeignKeyConstraint( + ["user_id"], + ["lazer_users.id"], + ), + sa.PrimaryKeyConstraint("id"), + ) + op.create_index( + op.f("ix_multiplayer_events_event_type"), + "multiplayer_events", + ["event_type"], + unique=False, + ) + op.create_index( + op.f("ix_multiplayer_events_id"), "multiplayer_events", ["id"], unique=False + ) + op.create_index( + op.f("ix_multiplayer_events_room_id"), + "multiplayer_events", + ["room_id"], + unique=False, + ) + op.create_index( + op.f("ix_multiplayer_events_user_id"), + "multiplayer_events", + ["user_id"], + unique=False, + ) + op.create_table( + "room_participated_users", + sa.Column("id", sa.BigInteger(), autoincrement=True, nullable=False), + sa.Column("room_id", sa.Integer(), nullable=False), + sa.Column("user_id", sa.BigInteger(), nullable=False), + sa.Column("joined_at", sa.DateTime(timezone=True), nullable=False), + sa.Column("left_at", sa.DateTime(timezone=True), nullable=True), + sa.ForeignKeyConstraint( + ["room_id"], + ["rooms.id"], + ), + sa.ForeignKeyConstraint( + ["user_id"], + ["lazer_users.id"], + ), + sa.PrimaryKeyConstraint("id"), + ) + op.create_table( + "room_playlists", + sa.Column("id", sa.Integer(), nullable=False), + sa.Column("owner_id", sa.BigInteger(), nullable=True), + sa.Column("ruleset_id", sa.Integer(), nullable=False), + sa.Column("expired", sa.Boolean(), nullable=False), + sa.Column("playlist_order", sa.Integer(), nullable=False), + sa.Column("played_at", sa.DateTime(timezone=True), nullable=True), + sa.Column("allowed_mods", sa.JSON(), nullable=True), + sa.Column("required_mods", sa.JSON(), nullable=True), + sa.Column("beatmap_id", sa.Integer(), nullable=False), + sa.Column("freestyle", sa.Boolean(), nullable=False), + sa.Column("db_id", sa.Integer(), nullable=False), + sa.Column("room_id", sa.Integer(), nullable=False), + sa.ForeignKeyConstraint( + ["beatmap_id"], + ["beatmaps.id"], + ), + sa.ForeignKeyConstraint( + ["owner_id"], + ["lazer_users.id"], + ), + sa.ForeignKeyConstraint( + ["room_id"], + ["rooms.id"], + ), + sa.PrimaryKeyConstraint("db_id"), + ) + op.create_index( + op.f("ix_room_playlists_db_id"), "room_playlists", ["db_id"], unique=False + ) + op.create_index( + op.f("ix_room_playlists_id"), "room_playlists", ["id"], unique=False + ) + op.create_table( + "score_tokens", + sa.Column("score_id", sa.BigInteger(), nullable=True), + sa.Column( + "ruleset_id", + sa.Enum("OSU", "TAIKO", "FRUITS", "MANIA", name="gamemode"), + nullable=False, + ), + sa.Column("playlist_item_id", sa.Integer(), nullable=True), + sa.Column("created_at", sa.DateTime(), nullable=True), + sa.Column("updated_at", sa.DateTime(), nullable=True), + sa.Column("id", sa.BigInteger(), autoincrement=True, nullable=False), + sa.Column("user_id", sa.BigInteger(), nullable=True), + sa.Column("beatmap_id", sa.Integer(), nullable=False), + sa.ForeignKeyConstraint( + ["beatmap_id"], + ["beatmaps.id"], + ), + sa.ForeignKeyConstraint( + ["user_id"], + ["lazer_users.id"], + ), + sa.PrimaryKeyConstraint("id"), + ) + op.create_index( + "idx_user_playlist", + "score_tokens", + ["user_id", "playlist_item_id"], + unique=False, + ) + op.create_index(op.f("ix_score_tokens_id"), "score_tokens", ["id"], unique=False) + op.create_table( + "scores", + sa.Column("accuracy", sa.Float(), nullable=False), + sa.Column( + "map_md5", sqlmodel.sql.sqltypes.AutoString(length=32), nullable=False + ), + sa.Column("build_id", sa.Integer(), nullable=True), + sa.Column("classic_total_score", sa.BigInteger(), nullable=True), + sa.Column("ended_at", sa.DateTime(), nullable=True), + sa.Column("has_replay", sa.Boolean(), nullable=False), + sa.Column("max_combo", sa.Integer(), nullable=False), + sa.Column("mods", sa.JSON(), nullable=True), + sa.Column("passed", sa.Boolean(), nullable=False), + sa.Column("playlist_item_id", sa.Integer(), nullable=True), + sa.Column("pp", sa.Float(), nullable=False), + sa.Column("preserve", sa.Boolean(), nullable=False), + sa.Column( + "rank", + sa.Enum("X", "XH", "S", "SH", "A", "B", "C", "D", "F", name="rank"), + nullable=False, + ), + sa.Column("room_id", sa.Integer(), nullable=True), + sa.Column("started_at", sa.DateTime(), nullable=True), + sa.Column("total_score", sa.BigInteger(), nullable=True), + sa.Column("total_score_without_mods", sa.BigInteger(), nullable=True), + sa.Column("type", sqlmodel.sql.sqltypes.AutoString(), nullable=False), + sa.Column("beatmap_id", sa.Integer(), nullable=False), + sa.Column("id", sa.BigInteger(), autoincrement=True, nullable=False), + sa.Column("user_id", sa.BigInteger(), nullable=True), + sa.Column("n300", sa.Integer(), nullable=False), + sa.Column("n100", sa.Integer(), nullable=False), + sa.Column("n50", sa.Integer(), nullable=False), + sa.Column("nmiss", sa.Integer(), nullable=False), + sa.Column("ngeki", sa.Integer(), nullable=False), + sa.Column("nkatu", sa.Integer(), nullable=False), + sa.Column("nlarge_tick_miss", sa.Integer(), nullable=True), + sa.Column("nlarge_tick_hit", sa.Integer(), nullable=True), + sa.Column("nslider_tail_hit", sa.Integer(), nullable=True), + sa.Column("nsmall_tick_hit", sa.Integer(), nullable=True), + sa.Column( + "gamemode", + sa.Enum("OSU", "TAIKO", "FRUITS", "MANIA", name="gamemode"), + nullable=False, + ), + sa.ForeignKeyConstraint( + ["beatmap_id"], + ["beatmaps.id"], + ), + sa.ForeignKeyConstraint( + ["user_id"], + ["lazer_users.id"], + ), + sa.PrimaryKeyConstraint("id"), + ) + op.create_index( + op.f("ix_scores_beatmap_id"), "scores", ["beatmap_id"], unique=False + ) + op.create_index(op.f("ix_scores_gamemode"), "scores", ["gamemode"], unique=False) + op.create_index(op.f("ix_scores_map_md5"), "scores", ["map_md5"], unique=False) + op.create_index(op.f("ix_scores_user_id"), "scores", ["user_id"], unique=False) + op.create_table( + "best_scores", + sa.Column("user_id", sa.BigInteger(), nullable=True), + sa.Column("score_id", sa.BigInteger(), nullable=False), + sa.Column("beatmap_id", sa.Integer(), nullable=False), + sa.Column( + "gamemode", + sa.Enum("OSU", "TAIKO", "FRUITS", "MANIA", name="gamemode"), + nullable=False, + ), + sa.Column("pp", sa.Float(), nullable=True), + sa.Column("acc", sa.Float(), nullable=True), + sa.ForeignKeyConstraint( + ["beatmap_id"], + ["beatmaps.id"], + ), + sa.ForeignKeyConstraint( + ["score_id"], + ["scores.id"], + ), + sa.ForeignKeyConstraint( + ["user_id"], + ["lazer_users.id"], + ), + sa.PrimaryKeyConstraint("score_id"), + ) + op.create_index( + op.f("ix_best_scores_beatmap_id"), "best_scores", ["beatmap_id"], unique=False + ) + op.create_index( + op.f("ix_best_scores_gamemode"), "best_scores", ["gamemode"], unique=False + ) + op.create_index( + op.f("ix_best_scores_user_id"), "best_scores", ["user_id"], unique=False + ) + op.create_table( + "playlist_best_scores", + sa.Column("user_id", sa.BigInteger(), nullable=True), + sa.Column("score_id", sa.BigInteger(), nullable=False), + sa.Column("room_id", sa.Integer(), nullable=False), + sa.Column("playlist_id", sa.Integer(), nullable=False), + sa.Column("total_score", sa.BigInteger(), nullable=True), + sa.Column("attempts", sa.Integer(), nullable=False), + sa.ForeignKeyConstraint( + ["playlist_id"], + ["room_playlists.id"], + ), + sa.ForeignKeyConstraint( + ["room_id"], + ["rooms.id"], + ), + sa.ForeignKeyConstraint( + ["score_id"], + ["scores.id"], + ), + sa.ForeignKeyConstraint( + ["user_id"], + ["lazer_users.id"], + ), + sa.PrimaryKeyConstraint("score_id"), + ) + op.create_index( + op.f("ix_playlist_best_scores_playlist_id"), + "playlist_best_scores", + ["playlist_id"], + unique=False, + ) + op.create_index( + op.f("ix_playlist_best_scores_room_id"), + "playlist_best_scores", + ["room_id"], + unique=False, + ) + op.create_index( + op.f("ix_playlist_best_scores_user_id"), + "playlist_best_scores", + ["user_id"], + unique=False, + ) + op.create_table( + "total_score_best_scores", + sa.Column("user_id", sa.BigInteger(), nullable=True), + sa.Column("score_id", sa.BigInteger(), nullable=False), + sa.Column("beatmap_id", sa.Integer(), nullable=False), + sa.Column( + "gamemode", + sa.Enum("OSU", "TAIKO", "FRUITS", "MANIA", name="gamemode"), + nullable=False, + ), + sa.Column("total_score", sa.BigInteger(), nullable=True), + sa.Column("mods", sa.JSON(), nullable=True), + sa.Column( + "rank", + sa.Enum("X", "XH", "S", "SH", "A", "B", "C", "D", "F", name="rank"), + nullable=False, + ), + sa.ForeignKeyConstraint( + ["beatmap_id"], + ["beatmaps.id"], + ), + sa.ForeignKeyConstraint( + ["score_id"], + ["scores.id"], + ), + sa.ForeignKeyConstraint( + ["user_id"], + ["lazer_users.id"], + ), + sa.PrimaryKeyConstraint("score_id"), + ) + op.create_index( + op.f("ix_total_score_best_scores_beatmap_id"), + "total_score_best_scores", + ["beatmap_id"], + unique=False, + ) + op.create_index( + op.f("ix_total_score_best_scores_gamemode"), + "total_score_best_scores", + ["gamemode"], + unique=False, + ) + op.create_index( + op.f("ix_total_score_best_scores_user_id"), + "total_score_best_scores", + ["user_id"], + unique=False, + ) + # ### end Alembic commands ### + + +def downgrade() -> None: + """Downgrade schema.""" + # ### commands auto generated by Alembic - please adjust! ### + op.drop_index( + op.f("ix_total_score_best_scores_user_id"), table_name="total_score_best_scores" + ) + op.drop_index( + op.f("ix_total_score_best_scores_gamemode"), + table_name="total_score_best_scores", + ) + op.drop_index( + op.f("ix_total_score_best_scores_beatmap_id"), + table_name="total_score_best_scores", + ) + op.drop_table("total_score_best_scores") + op.drop_index( + op.f("ix_playlist_best_scores_user_id"), table_name="playlist_best_scores" + ) + op.drop_index( + op.f("ix_playlist_best_scores_room_id"), table_name="playlist_best_scores" + ) + op.drop_index( + op.f("ix_playlist_best_scores_playlist_id"), table_name="playlist_best_scores" + ) + op.drop_table("playlist_best_scores") + op.drop_index(op.f("ix_best_scores_user_id"), table_name="best_scores") + op.drop_index(op.f("ix_best_scores_gamemode"), table_name="best_scores") + op.drop_index(op.f("ix_best_scores_beatmap_id"), table_name="best_scores") + op.drop_table("best_scores") + op.drop_index(op.f("ix_scores_user_id"), table_name="scores") + op.drop_index(op.f("ix_scores_map_md5"), table_name="scores") + op.drop_index(op.f("ix_scores_gamemode"), table_name="scores") + op.drop_index(op.f("ix_scores_beatmap_id"), table_name="scores") + op.drop_table("scores") + op.drop_index(op.f("ix_score_tokens_id"), table_name="score_tokens") + op.drop_index("idx_user_playlist", table_name="score_tokens") + op.drop_table("score_tokens") + op.drop_index(op.f("ix_room_playlists_id"), table_name="room_playlists") + op.drop_index(op.f("ix_room_playlists_db_id"), table_name="room_playlists") + op.drop_table("room_playlists") + op.drop_table("room_participated_users") + op.drop_index( + op.f("ix_multiplayer_events_user_id"), table_name="multiplayer_events" + ) + op.drop_index( + op.f("ix_multiplayer_events_room_id"), table_name="multiplayer_events" + ) + op.drop_index(op.f("ix_multiplayer_events_id"), table_name="multiplayer_events") + op.drop_index( + op.f("ix_multiplayer_events_event_type"), table_name="multiplayer_events" + ) + op.drop_table("multiplayer_events") + op.drop_index( + op.f("ix_item_attempts_count_user_id"), table_name="item_attempts_count" + ) + op.drop_index( + op.f("ix_item_attempts_count_room_id"), table_name="item_attempts_count" + ) + op.drop_table("item_attempts_count") + op.drop_index( + op.f("ix_beatmap_playcounts_user_id"), table_name="beatmap_playcounts" + ) + op.drop_index( + op.f("ix_beatmap_playcounts_beatmap_id"), table_name="beatmap_playcounts" + ) + op.drop_table("beatmap_playcounts") + op.drop_index( + op.f("ix_user_account_history_user_id"), table_name="user_account_history" + ) + op.drop_index(op.f("ix_user_account_history_id"), table_name="user_account_history") + op.drop_table("user_account_history") + op.drop_index(op.f("ix_team_members_id"), table_name="team_members") + op.drop_table("team_members") + op.drop_index(op.f("ix_rooms_name"), table_name="rooms") + op.drop_index(op.f("ix_rooms_id"), table_name="rooms") + op.drop_index(op.f("ix_rooms_host_id"), table_name="rooms") + op.drop_index(op.f("ix_rooms_category"), table_name="rooms") + op.drop_table("rooms") + op.drop_index(op.f("ix_relationship_user_id"), table_name="relationship") + op.drop_index(op.f("ix_relationship_target_id"), table_name="relationship") + op.drop_table("relationship") + op.drop_index(op.f("ix_oauth_tokens_user_id"), table_name="oauth_tokens") + op.drop_index(op.f("ix_oauth_tokens_id"), table_name="oauth_tokens") + op.drop_table("oauth_tokens") + op.drop_index(op.f("ix_monthly_playcounts_year"), table_name="monthly_playcounts") + op.drop_index( + op.f("ix_monthly_playcounts_user_id"), table_name="monthly_playcounts" + ) + op.drop_index(op.f("ix_monthly_playcounts_month"), table_name="monthly_playcounts") + op.drop_table("monthly_playcounts") + op.drop_index( + op.f("ix_lazer_user_statistics_user_id"), table_name="lazer_user_statistics" + ) + op.drop_table("lazer_user_statistics") + op.drop_index( + op.f("ix_lazer_user_achievements_id"), table_name="lazer_user_achievements" + ) + op.drop_table("lazer_user_achievements") + op.drop_index( + op.f("ix_favourite_beatmapset_user_id"), table_name="favourite_beatmapset" + ) + op.drop_index( + op.f("ix_favourite_beatmapset_beatmapset_id"), table_name="favourite_beatmapset" + ) + op.drop_table("favourite_beatmapset") + op.drop_index( + op.f("ix_daily_challenge_stats_user_id"), table_name="daily_challenge_stats" + ) + op.drop_table("daily_challenge_stats") + op.drop_index(op.f("ix_beatmaps_id"), table_name="beatmaps") + op.drop_index(op.f("ix_beatmaps_checksum"), table_name="beatmaps") + op.drop_index(op.f("ix_beatmaps_beatmapset_id"), table_name="beatmaps") + op.drop_table("beatmaps") + op.drop_index(op.f("ix_teams_id"), table_name="teams") + op.drop_table("teams") + op.drop_index(op.f("ix_lazer_users_username"), table_name="lazer_users") + op.drop_index(op.f("ix_lazer_users_id"), table_name="lazer_users") + op.drop_index(op.f("ix_lazer_users_email"), table_name="lazer_users") + op.drop_index(op.f("ix_lazer_users_country_code"), table_name="lazer_users") + op.drop_table("lazer_users") + op.drop_index(op.f("ix_beatmapsets_id"), table_name="beatmapsets") + op.drop_index(op.f("ix_beatmapsets_artist_unicode"), table_name="beatmapsets") + op.drop_index(op.f("ix_beatmapsets_artist"), table_name="beatmapsets") + op.drop_table("beatmapsets") + # ### end Alembic commands ###