331 lines
14 KiB
Python
331 lines
14 KiB
Python
"""music schema
|
|
|
|
Revision ID: e670d6c41d0c
|
|
Revises: 0001_auth_users
|
|
Create Date: 2026-06-07 11:37:41.420644
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from collections.abc import Sequence
|
|
|
|
import sqlalchemy as sa
|
|
from alembic import op
|
|
|
|
# revision identifiers, used by Alembic.
|
|
revision: str = "e670d6c41d0c"
|
|
down_revision: str | None = "0001_auth_users"
|
|
branch_labels: str | Sequence[str] | None = None
|
|
depends_on: str | Sequence[str] | None = None
|
|
|
|
|
|
def upgrade() -> None:
|
|
# ### commands auto generated by Alembic - please adjust! ###
|
|
op.create_table(
|
|
"artists",
|
|
sa.Column("name", sa.String(length=512), nullable=False),
|
|
sa.Column("musicbrainz_id", sa.String(length=36), nullable=True),
|
|
sa.Column("id", sa.Uuid(), nullable=False),
|
|
sa.Column(
|
|
"created_at",
|
|
sa.DateTime(timezone=True),
|
|
server_default=sa.text("now()"),
|
|
nullable=False,
|
|
),
|
|
sa.Column(
|
|
"updated_at",
|
|
sa.DateTime(timezone=True),
|
|
server_default=sa.text("now()"),
|
|
nullable=False,
|
|
),
|
|
sa.PrimaryKeyConstraint("id", name=op.f("pk_artists")),
|
|
)
|
|
op.create_index(op.f("ix_artists_musicbrainz_id"), "artists", ["musicbrainz_id"], unique=False)
|
|
op.create_index(op.f("ix_artists_name"), "artists", ["name"], unique=False)
|
|
op.create_table(
|
|
"albums",
|
|
sa.Column("title", sa.String(length=1024), nullable=False),
|
|
sa.Column("artist_id", sa.Uuid(), nullable=False),
|
|
sa.Column("year", sa.Integer(), nullable=True),
|
|
sa.Column("cover_path", sa.String(length=1024), nullable=True),
|
|
sa.Column("musicbrainz_id", sa.String(length=36), nullable=True),
|
|
sa.Column("id", sa.Uuid(), nullable=False),
|
|
sa.Column(
|
|
"created_at",
|
|
sa.DateTime(timezone=True),
|
|
server_default=sa.text("now()"),
|
|
nullable=False,
|
|
),
|
|
sa.Column(
|
|
"updated_at",
|
|
sa.DateTime(timezone=True),
|
|
server_default=sa.text("now()"),
|
|
nullable=False,
|
|
),
|
|
sa.ForeignKeyConstraint(
|
|
["artist_id"],
|
|
["artists.id"],
|
|
name=op.f("fk_albums_artist_id_artists"),
|
|
ondelete="CASCADE",
|
|
),
|
|
sa.PrimaryKeyConstraint("id", name=op.f("pk_albums")),
|
|
)
|
|
op.create_index(op.f("ix_albums_artist_id"), "albums", ["artist_id"], unique=False)
|
|
op.create_index(op.f("ix_albums_musicbrainz_id"), "albums", ["musicbrainz_id"], unique=False)
|
|
op.create_index(op.f("ix_albums_title"), "albums", ["title"], unique=False)
|
|
op.create_table(
|
|
"download_jobs",
|
|
sa.Column("source", sa.String(length=32), nullable=False),
|
|
sa.Column("source_id", sa.String(length=512), nullable=True),
|
|
sa.Column("query", sa.String(length=1024), nullable=True),
|
|
sa.Column("requested_by", sa.Uuid(), nullable=True),
|
|
sa.Column("status", sa.String(length=16), nullable=False),
|
|
sa.Column("progress", sa.Float(), nullable=False),
|
|
sa.Column("error_message", sa.Text(), nullable=True),
|
|
sa.Column("retry_count", sa.Integer(), nullable=False),
|
|
sa.Column("id", sa.Uuid(), nullable=False),
|
|
sa.Column(
|
|
"created_at",
|
|
sa.DateTime(timezone=True),
|
|
server_default=sa.text("now()"),
|
|
nullable=False,
|
|
),
|
|
sa.Column(
|
|
"updated_at",
|
|
sa.DateTime(timezone=True),
|
|
server_default=sa.text("now()"),
|
|
nullable=False,
|
|
),
|
|
sa.ForeignKeyConstraint(
|
|
["requested_by"],
|
|
["users.id"],
|
|
name=op.f("fk_download_jobs_requested_by_users"),
|
|
ondelete="SET NULL",
|
|
),
|
|
sa.PrimaryKeyConstraint("id", name=op.f("pk_download_jobs")),
|
|
)
|
|
op.create_index(
|
|
op.f("ix_download_jobs_requested_by"), "download_jobs", ["requested_by"], unique=False
|
|
)
|
|
op.create_index(op.f("ix_download_jobs_status"), "download_jobs", ["status"], unique=False)
|
|
op.create_table(
|
|
"playlists",
|
|
sa.Column("name", sa.String(length=512), nullable=False),
|
|
sa.Column("description", sa.String(length=2048), nullable=True),
|
|
sa.Column("owner_id", sa.Uuid(), nullable=False),
|
|
sa.Column("cover_path", sa.String(length=1024), nullable=True),
|
|
sa.Column("version", sa.Integer(), nullable=False),
|
|
sa.Column("id", sa.Uuid(), nullable=False),
|
|
sa.Column(
|
|
"created_at",
|
|
sa.DateTime(timezone=True),
|
|
server_default=sa.text("now()"),
|
|
nullable=False,
|
|
),
|
|
sa.Column(
|
|
"updated_at",
|
|
sa.DateTime(timezone=True),
|
|
server_default=sa.text("now()"),
|
|
nullable=False,
|
|
),
|
|
sa.ForeignKeyConstraint(
|
|
["owner_id"], ["users.id"], name=op.f("fk_playlists_owner_id_users"), ondelete="CASCADE"
|
|
),
|
|
sa.PrimaryKeyConstraint("id", name=op.f("pk_playlists")),
|
|
)
|
|
op.create_index(op.f("ix_playlists_owner_id"), "playlists", ["owner_id"], unique=False)
|
|
op.create_table(
|
|
"tracks",
|
|
sa.Column("title", sa.String(length=1024), nullable=False),
|
|
sa.Column("artist_id", sa.Uuid(), nullable=False),
|
|
sa.Column("album_id", sa.Uuid(), nullable=True),
|
|
sa.Column("track_number", sa.Integer(), nullable=True),
|
|
sa.Column("duration_seconds", sa.Integer(), nullable=True),
|
|
sa.Column("genre", sa.String(length=255), nullable=True),
|
|
sa.Column("year", sa.Integer(), nullable=True),
|
|
sa.Column("file_path", sa.String(length=2048), nullable=False),
|
|
sa.Column("file_format", sa.String(length=32), nullable=False),
|
|
sa.Column("file_size", sa.Integer(), nullable=False),
|
|
sa.Column("bitrate", sa.Integer(), nullable=True),
|
|
sa.Column("acoustid_fingerprint", sa.String(length=64), nullable=True),
|
|
sa.Column("musicbrainz_id", sa.String(length=36), nullable=True),
|
|
sa.Column("source", sa.String(length=32), nullable=False),
|
|
sa.Column("source_id", sa.String(length=512), nullable=False),
|
|
sa.Column("is_replaceable", sa.Boolean(), nullable=False),
|
|
sa.Column("storage_policy", sa.String(length=16), nullable=False),
|
|
sa.Column("metadata_status", sa.String(length=16), nullable=False),
|
|
sa.Column("added_by", sa.Uuid(), nullable=True),
|
|
sa.Column("id", sa.Uuid(), nullable=False),
|
|
sa.Column(
|
|
"created_at",
|
|
sa.DateTime(timezone=True),
|
|
server_default=sa.text("now()"),
|
|
nullable=False,
|
|
),
|
|
sa.Column(
|
|
"updated_at",
|
|
sa.DateTime(timezone=True),
|
|
server_default=sa.text("now()"),
|
|
nullable=False,
|
|
),
|
|
sa.ForeignKeyConstraint(
|
|
["added_by"], ["users.id"], name=op.f("fk_tracks_added_by_users"), ondelete="SET NULL"
|
|
),
|
|
sa.ForeignKeyConstraint(
|
|
["album_id"], ["albums.id"], name=op.f("fk_tracks_album_id_albums"), ondelete="SET NULL"
|
|
),
|
|
sa.ForeignKeyConstraint(
|
|
["artist_id"],
|
|
["artists.id"],
|
|
name=op.f("fk_tracks_artist_id_artists"),
|
|
ondelete="CASCADE",
|
|
),
|
|
sa.PrimaryKeyConstraint("id", name=op.f("pk_tracks")),
|
|
sa.UniqueConstraint("source", "source_id", name="uq_tracks_source_source_id"),
|
|
)
|
|
op.create_index(
|
|
op.f("ix_tracks_acoustid_fingerprint"), "tracks", ["acoustid_fingerprint"], unique=False
|
|
)
|
|
op.create_index(op.f("ix_tracks_added_by"), "tracks", ["added_by"], unique=False)
|
|
op.create_index(op.f("ix_tracks_album_id"), "tracks", ["album_id"], unique=False)
|
|
op.create_index(op.f("ix_tracks_artist_id"), "tracks", ["artist_id"], unique=False)
|
|
op.create_index(op.f("ix_tracks_genre"), "tracks", ["genre"], unique=False)
|
|
op.create_index(op.f("ix_tracks_musicbrainz_id"), "tracks", ["musicbrainz_id"], unique=False)
|
|
op.create_index(op.f("ix_tracks_title"), "tracks", ["title"], unique=False)
|
|
op.create_table(
|
|
"likes",
|
|
sa.Column("user_id", sa.Uuid(), nullable=False),
|
|
sa.Column("track_id", sa.Uuid(), nullable=False),
|
|
sa.Column("value", sa.String(length=16), nullable=False),
|
|
sa.Column(
|
|
"created_at",
|
|
sa.DateTime(timezone=True),
|
|
server_default=sa.text("now()"),
|
|
nullable=False,
|
|
),
|
|
sa.Column("id", sa.Uuid(), nullable=False),
|
|
sa.ForeignKeyConstraint(
|
|
["track_id"], ["tracks.id"], name=op.f("fk_likes_track_id_tracks"), ondelete="CASCADE"
|
|
),
|
|
sa.ForeignKeyConstraint(
|
|
["user_id"], ["users.id"], name=op.f("fk_likes_user_id_users"), ondelete="CASCADE"
|
|
),
|
|
sa.PrimaryKeyConstraint("id", name=op.f("pk_likes")),
|
|
)
|
|
op.create_index("ix_likes_user_id_track_id", "likes", ["user_id", "track_id"], unique=False)
|
|
op.create_table(
|
|
"lyrics",
|
|
sa.Column("track_id", sa.Uuid(), nullable=False),
|
|
sa.Column("synced", sa.Text(), nullable=True),
|
|
sa.Column("plain", sa.Text(), nullable=True),
|
|
sa.Column("source", sa.String(length=64), nullable=True),
|
|
sa.Column("status", sa.String(length=16), nullable=False),
|
|
sa.Column(
|
|
"fetched_at",
|
|
sa.DateTime(timezone=True),
|
|
server_default=sa.text("now()"),
|
|
nullable=False,
|
|
),
|
|
sa.Column("id", sa.Uuid(), nullable=False),
|
|
sa.ForeignKeyConstraint(
|
|
["track_id"], ["tracks.id"], name=op.f("fk_lyrics_track_id_tracks"), ondelete="CASCADE"
|
|
),
|
|
sa.PrimaryKeyConstraint("id", name=op.f("pk_lyrics")),
|
|
sa.UniqueConstraint("track_id", name=op.f("uq_lyrics_track_id")),
|
|
)
|
|
op.create_table(
|
|
"play_history",
|
|
sa.Column("user_id", sa.Uuid(), nullable=False),
|
|
sa.Column("track_id", sa.Uuid(), nullable=False),
|
|
sa.Column(
|
|
"played_at", sa.DateTime(timezone=True), server_default=sa.text("now()"), nullable=False
|
|
),
|
|
sa.Column("play_duration_seconds", sa.Integer(), nullable=True),
|
|
sa.Column("completed", sa.Boolean(), nullable=False),
|
|
sa.Column("id", sa.Uuid(), nullable=False),
|
|
sa.ForeignKeyConstraint(
|
|
["track_id"],
|
|
["tracks.id"],
|
|
name=op.f("fk_play_history_track_id_tracks"),
|
|
ondelete="CASCADE",
|
|
),
|
|
sa.ForeignKeyConstraint(
|
|
["user_id"],
|
|
["users.id"],
|
|
name=op.f("fk_play_history_user_id_users"),
|
|
ondelete="CASCADE",
|
|
),
|
|
sa.PrimaryKeyConstraint("id", name=op.f("pk_play_history")),
|
|
)
|
|
op.create_index(op.f("ix_play_history_track_id"), "play_history", ["track_id"], unique=False)
|
|
op.create_index(
|
|
"ix_play_history_user_id_played_at", "play_history", ["user_id", "played_at"], unique=False
|
|
)
|
|
op.create_table(
|
|
"playlist_tracks",
|
|
sa.Column("playlist_id", sa.Uuid(), nullable=False),
|
|
sa.Column("track_id", sa.Uuid(), nullable=False),
|
|
sa.Column("position", sa.Float(), nullable=False),
|
|
sa.Column(
|
|
"added_at", sa.DateTime(timezone=True), server_default=sa.text("now()"), nullable=False
|
|
),
|
|
sa.Column("id", sa.Uuid(), nullable=False),
|
|
sa.ForeignKeyConstraint(
|
|
["playlist_id"],
|
|
["playlists.id"],
|
|
name=op.f("fk_playlist_tracks_playlist_id_playlists"),
|
|
ondelete="CASCADE",
|
|
),
|
|
sa.ForeignKeyConstraint(
|
|
["track_id"],
|
|
["tracks.id"],
|
|
name=op.f("fk_playlist_tracks_track_id_tracks"),
|
|
ondelete="CASCADE",
|
|
),
|
|
sa.PrimaryKeyConstraint("id", name=op.f("pk_playlist_tracks")),
|
|
sa.UniqueConstraint(
|
|
"playlist_id", "track_id", name="uq_playlist_tracks_playlist_id_track_id"
|
|
),
|
|
)
|
|
op.create_index(
|
|
op.f("ix_playlist_tracks_playlist_id"), "playlist_tracks", ["playlist_id"], unique=False
|
|
)
|
|
op.create_index(
|
|
op.f("ix_playlist_tracks_track_id"), "playlist_tracks", ["track_id"], unique=False
|
|
)
|
|
# ### end Alembic commands ###
|
|
|
|
|
|
def downgrade() -> None:
|
|
# ### commands auto generated by Alembic - please adjust! ###
|
|
op.drop_index(op.f("ix_playlist_tracks_track_id"), table_name="playlist_tracks")
|
|
op.drop_index(op.f("ix_playlist_tracks_playlist_id"), table_name="playlist_tracks")
|
|
op.drop_table("playlist_tracks")
|
|
op.drop_index("ix_play_history_user_id_played_at", table_name="play_history")
|
|
op.drop_index(op.f("ix_play_history_track_id"), table_name="play_history")
|
|
op.drop_table("play_history")
|
|
op.drop_table("lyrics")
|
|
op.drop_index("ix_likes_user_id_track_id", table_name="likes")
|
|
op.drop_table("likes")
|
|
op.drop_index(op.f("ix_tracks_title"), table_name="tracks")
|
|
op.drop_index(op.f("ix_tracks_musicbrainz_id"), table_name="tracks")
|
|
op.drop_index(op.f("ix_tracks_genre"), table_name="tracks")
|
|
op.drop_index(op.f("ix_tracks_artist_id"), table_name="tracks")
|
|
op.drop_index(op.f("ix_tracks_album_id"), table_name="tracks")
|
|
op.drop_index(op.f("ix_tracks_added_by"), table_name="tracks")
|
|
op.drop_index(op.f("ix_tracks_acoustid_fingerprint"), table_name="tracks")
|
|
op.drop_table("tracks")
|
|
op.drop_index(op.f("ix_playlists_owner_id"), table_name="playlists")
|
|
op.drop_table("playlists")
|
|
op.drop_index(op.f("ix_download_jobs_status"), table_name="download_jobs")
|
|
op.drop_index(op.f("ix_download_jobs_requested_by"), table_name="download_jobs")
|
|
op.drop_table("download_jobs")
|
|
op.drop_index(op.f("ix_albums_title"), table_name="albums")
|
|
op.drop_index(op.f("ix_albums_musicbrainz_id"), table_name="albums")
|
|
op.drop_index(op.f("ix_albums_artist_id"), table_name="albums")
|
|
op.drop_table("albums")
|
|
op.drop_index(op.f("ix_artists_name"), table_name="artists")
|
|
op.drop_index(op.f("ix_artists_musicbrainz_id"), table_name="artists")
|
|
op.drop_table("artists")
|
|
# ### end Alembic commands ###
|