Fix docker

This commit is contained in:
2025-10-30 22:54:20 +11:00
parent 9c6ed82a56
commit 2ba4ff3113
6 changed files with 74 additions and 112 deletions
@@ -21,6 +21,46 @@ depends_on: Union[str, Sequence[str], None] = None
def upgrade() -> None:
"""Upgrade schema."""
# ### commands auto generated by Alembic - please adjust! ###
# Create all tables
op.create_table('music',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('title', sa.String(), nullable=True),
sa.Column('artist', sa.String(), nullable=True),
sa.Column('album', sa.String(), nullable=True),
sa.Column('duration', sa.Float(), nullable=True),
sa.Column('file_path', sa.String(), nullable=True),
sa.Column('file_size', sa.Integer(), nullable=True),
sa.Column('file_format', sa.String(), nullable=True),
sa.Column('file_location', sa.String(), nullable=True),
sa.Column('file_exists', sa.Boolean(), nullable=True),
sa.Column('source_url', sa.String(), nullable=True),
sa.Column('source_type', sa.String(), nullable=True),
sa.Column('thumbnail', sa.String(), nullable=True),
sa.Column('lyrics', sa.Text(), nullable=True),
sa.Column('created_at', sa.DateTime(), nullable=True),
sa.Column('updated_at', sa.DateTime(), nullable=True),
sa.Column('last_scanned_at', sa.DateTime(), nullable=True),
sa.PrimaryKeyConstraint('id')
)
with op.batch_alter_table('music', schema=None) as batch_op:
batch_op.create_index(batch_op.f('ix_music_artist'), ['artist'], unique=False)
batch_op.create_index(batch_op.f('ix_music_id'), ['id'], unique=False)
batch_op.create_index(batch_op.f('ix_music_title'), ['title'], unique=False)
batch_op.create_unique_constraint('uq_music_file_path', ['file_path'])
op.create_table('playlists',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('name', sa.String(), nullable=True),
sa.Column('description', sa.Text(), nullable=True),
sa.Column('thumbnail', sa.String(), nullable=True),
sa.Column('created_at', sa.DateTime(), nullable=True),
sa.Column('updated_at', sa.DateTime(), nullable=True),
sa.PrimaryKeyConstraint('id')
)
with op.batch_alter_table('playlists', schema=None) as batch_op:
batch_op.create_index(batch_op.f('ix_playlists_id'), ['id'], unique=False)
batch_op.create_index(batch_op.f('ix_playlists_name'), ['name'], unique=True)
op.create_table('app_settings',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('key', sa.String(), nullable=True),
@@ -32,27 +72,37 @@ def upgrade() -> None:
batch_op.create_index(batch_op.f('ix_app_settings_id'), ['id'], unique=False)
batch_op.create_index(batch_op.f('ix_app_settings_key'), ['key'], unique=True)
with op.batch_alter_table('music', schema=None) as batch_op:
batch_op.add_column(sa.Column('file_format', sa.String(), nullable=True))
batch_op.add_column(sa.Column('file_location', sa.String(), nullable=True))
batch_op.add_column(sa.Column('file_exists', sa.Boolean(), nullable=True))
batch_op.add_column(sa.Column('last_scanned_at', sa.DateTime(), nullable=True))
op.create_table('playlist_music',
sa.Column('playlist_id', sa.Integer(), nullable=False),
sa.Column('music_id', sa.Integer(), nullable=False),
sa.Column('position', sa.Integer(), nullable=True),
sa.Column('added_at', sa.DateTime(), nullable=True),
sa.ForeignKeyConstraint(['music_id'], ['music.id'], ),
sa.ForeignKeyConstraint(['playlist_id'], ['playlists.id'], ),
sa.PrimaryKeyConstraint('playlist_id', 'music_id')
)
# ### end Alembic commands ###
def downgrade() -> None:
"""Downgrade schema."""
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table('music', schema=None) as batch_op:
batch_op.drop_column('last_scanned_at')
batch_op.drop_column('file_exists')
batch_op.drop_column('file_location')
batch_op.drop_column('file_format')
op.drop_table('playlist_music')
with op.batch_alter_table('app_settings', schema=None) as batch_op:
batch_op.drop_index(batch_op.f('ix_app_settings_key'))
batch_op.drop_index(batch_op.f('ix_app_settings_id'))
op.drop_table('app_settings')
with op.batch_alter_table('playlists', schema=None) as batch_op:
batch_op.drop_index(batch_op.f('ix_playlists_name'))
batch_op.drop_index(batch_op.f('ix_playlists_id'))
op.drop_table('playlists')
with op.batch_alter_table('music', schema=None) as batch_op:
batch_op.drop_constraint('uq_music_file_path', type_='unique')
batch_op.drop_index(batch_op.f('ix_music_title'))
batch_op.drop_index(batch_op.f('ix_music_id'))
batch_op.drop_index(batch_op.f('ix_music_artist'))
op.drop_table('music')
# ### end Alembic commands ###
@@ -1,51 +0,0 @@
"""Populate file_location and file_format
Revision ID: 49793394b596
Revises: c1fd223a3556
Create Date: 2025-10-30 21:56:40.131970
"""
from typing import Sequence, Union
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision: str = '49793394b596'
down_revision: Union[str, Sequence[str], None] = 'c1fd223a3556'
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
def upgrade() -> None:
"""Upgrade schema."""
# Populate file_location from MUSIC_DIR + file_path for existing records
# Note: This uses SQLite-specific syntax
op.execute("""
UPDATE music
SET file_location = './data/music/' || file_path
WHERE file_location IS NULL OR file_location = ''
""")
# Populate file_format from file_path extension
op.execute("""
UPDATE music
SET file_format = LOWER(
CASE
WHEN file_path LIKE '%.mp3' THEN 'mp3'
WHEN file_path LIKE '%.m4a' THEN 'm4a'
WHEN file_path LIKE '%.flac' THEN 'flac'
WHEN file_path LIKE '%.wav' THEN 'wav'
WHEN file_path LIKE '%.ogg' THEN 'ogg'
WHEN file_path LIKE '%.opus' THEN 'opus'
ELSE SUBSTR(file_path, INSTR(file_path, '.') + 1)
END
)
WHERE file_format IS NULL OR file_format = ''
""")
def downgrade() -> None:
"""Downgrade schema."""
pass
@@ -1,44 +0,0 @@
"""Add file tracking columns
Revision ID: c1fd223a3556
Revises: 01209c730b33
Create Date: 2025-10-30 21:48:22.894324
"""
from typing import Sequence, Union
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision: str = 'c1fd223a3556'
down_revision: Union[str, Sequence[str], None] = '01209c730b33'
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
def upgrade() -> None:
"""Upgrade schema."""
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table('music', schema=None) as batch_op:
batch_op.add_column(sa.Column('file_format', sa.String(), nullable=True))
batch_op.add_column(sa.Column('file_location', sa.String(), nullable=True))
batch_op.add_column(sa.Column('file_exists', sa.Boolean(), nullable=True))
batch_op.add_column(sa.Column('last_scanned_at', sa.DateTime(), nullable=True))
# Set default value for existing records
op.execute("UPDATE music SET file_exists = 1 WHERE file_exists IS NULL")
# ### end Alembic commands ###
def downgrade() -> None:
"""Downgrade schema."""
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table('music', schema=None) as batch_op:
batch_op.drop_column('last_scanned_at')
batch_op.drop_column('file_exists')
batch_op.drop_column('file_location')
batch_op.drop_column('file_format')
# ### end Alembic commands ###
+8 -1
View File
@@ -29,5 +29,12 @@ async def get_db():
async def init_db():
"""Initialize database connection pool
Note: Table creation is handled by Alembic migrations.
This function just ensures the connection pool is ready.
"""
# Just test the connection
async with engine.begin() as conn:
await conn.run_sync(Base.metadata.create_all)
# Connection pool is ready
pass
+2 -3
View File
@@ -80,9 +80,8 @@ async def lifespan(app: FastAPI):
os.makedirs(settings.LOCAL_MUSIC_DIR, exist_ok=True)
print(f"✅ LOCAL_MUSIC_DIR created: {settings.LOCAL_MUSIC_DIR}")
# Run database migrations
await run_migrations()
# Note: Database migrations are run by start.sh before uvicorn starts
# We just initialize the connection pool here
await init_db()
# Start scheduler
+1
View File
@@ -7,6 +7,7 @@ services:
- "8000:8000"
volumes:
- ./data:/app/data
- /Users/junv/Music/网易云音乐:/app/data/local-music
environment:
- PYTHONUNBUFFERED=1
- PYTHONPATH=/app/backend