Update db schema
Add queries table Add index to notecolours.substring Set up cascading deletes for queries, playdates and playlist_rows
This commit is contained in:
parent
c17e4b8122
commit
c01b47322f
@ -18,6 +18,7 @@ class DatabaseManager:
|
|||||||
def __init__(self, database_url: str, **kwargs: dict) -> None:
|
def __init__(self, database_url: str, **kwargs: dict) -> None:
|
||||||
if DatabaseManager.__instance is None:
|
if DatabaseManager.__instance is None:
|
||||||
self.db = Alchemical(database_url, **kwargs)
|
self.db = Alchemical(database_url, **kwargs)
|
||||||
|
self.db.create_all()
|
||||||
DatabaseManager.__instance = self
|
DatabaseManager.__instance = self
|
||||||
else:
|
else:
|
||||||
raise Exception("Attempted to create a second DatabaseManager instance")
|
raise Exception("Attempted to create a second DatabaseManager instance")
|
||||||
|
|||||||
@ -48,9 +48,11 @@ class PlaydatesTable(Model):
|
|||||||
|
|
||||||
id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)
|
id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)
|
||||||
lastplayed: Mapped[dt.datetime] = mapped_column(index=True)
|
lastplayed: Mapped[dt.datetime] = mapped_column(index=True)
|
||||||
track_id: Mapped[int] = mapped_column(ForeignKey("tracks.id"))
|
track_id: Mapped[int] = mapped_column(ForeignKey("tracks.id", ondelete="CASCADE"))
|
||||||
track: Mapped["TracksTable"] = relationship(
|
track: Mapped["TracksTable"] = relationship(
|
||||||
"TracksTable", back_populates="playdates"
|
"TracksTable",
|
||||||
|
back_populates="playdates",
|
||||||
|
cascade="all, delete-orphan",
|
||||||
)
|
)
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
@ -103,10 +105,11 @@ class PlaylistRowsTable(Model):
|
|||||||
)
|
)
|
||||||
|
|
||||||
playlist: Mapped[PlaylistsTable] = relationship(back_populates="rows")
|
playlist: Mapped[PlaylistsTable] = relationship(back_populates="rows")
|
||||||
track_id: Mapped[Optional[int]] = mapped_column(ForeignKey("tracks.id"))
|
track_id: Mapped[Optional[int]] = mapped_column(ForeignKey("tracks.id", ondelete="CASCADE"))
|
||||||
track: Mapped["TracksTable"] = relationship(
|
track: Mapped["TracksTable"] = relationship(
|
||||||
"TracksTable",
|
"TracksTable",
|
||||||
back_populates="playlistrows",
|
back_populates="playlistrows",
|
||||||
|
cascade="all, delete-orphan",
|
||||||
)
|
)
|
||||||
played: Mapped[bool] = mapped_column(
|
played: Mapped[bool] = mapped_column(
|
||||||
Boolean, nullable=False, index=False, default=False
|
Boolean, nullable=False, index=False, default=False
|
||||||
@ -127,7 +130,9 @@ class QueriesTable(Model):
|
|||||||
query: Mapped[str] = mapped_column(
|
query: Mapped[str] = mapped_column(
|
||||||
String(2048), index=False, default="", nullable=False
|
String(2048), index=False, default="", nullable=False
|
||||||
)
|
)
|
||||||
playlist_id: Mapped[int] = mapped_column(ForeignKey("playlists.id"), index=True)
|
playlist_id: Mapped[int] = mapped_column(
|
||||||
|
ForeignKey("playlists.id", ondelete="CASCADE"), index=True
|
||||||
|
)
|
||||||
playlist: Mapped[PlaylistsTable] = relationship(back_populates="query")
|
playlist: Mapped[PlaylistsTable] = relationship(back_populates="query")
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
|
|||||||
@ -36,7 +36,6 @@ if DATABASE_URL is None:
|
|||||||
if "unittest" in sys.modules and "sqlite" not in DATABASE_URL:
|
if "unittest" in sys.modules and "sqlite" not in DATABASE_URL:
|
||||||
raise ValueError("Unit tests running on non-Sqlite database")
|
raise ValueError("Unit tests running on non-Sqlite database")
|
||||||
db = DatabaseManager.get_instance(DATABASE_URL, engine_options=Config.ENGINE_OPTIONS).db
|
db = DatabaseManager.get_instance(DATABASE_URL, engine_options=Config.ENGINE_OPTIONS).db
|
||||||
# db.create_all()
|
|
||||||
|
|
||||||
|
|
||||||
# Database classes
|
# Database classes
|
||||||
|
|||||||
@ -1,27 +0,0 @@
|
|||||||
from importlib import import_module
|
|
||||||
from alembic import context
|
|
||||||
from alchemical.alembic.env import run_migrations
|
|
||||||
|
|
||||||
# this is the Alembic Config object, which provides
|
|
||||||
# access to the values within the .ini file in use.
|
|
||||||
config = context.config
|
|
||||||
|
|
||||||
# import the application's Alchemical instance
|
|
||||||
try:
|
|
||||||
import_mod, db_name = config.get_main_option('alchemical_db', '').split(
|
|
||||||
':')
|
|
||||||
db = getattr(import_module(import_mod), db_name)
|
|
||||||
except (ModuleNotFoundError, AttributeError):
|
|
||||||
raise ValueError(
|
|
||||||
'Could not import the Alchemical database instance. '
|
|
||||||
'Ensure that the alchemical_db setting in alembic.ini is correct.'
|
|
||||||
)
|
|
||||||
|
|
||||||
# run the migration engine
|
|
||||||
# The dictionary provided as second argument includes options to pass to the
|
|
||||||
# Alembic context. For details on what other options are available, see
|
|
||||||
# https://alembic.sqlalchemy.org/en/latest/autogenerate.html
|
|
||||||
run_migrations(db, {
|
|
||||||
'render_as_batch': True,
|
|
||||||
'compare_type': True,
|
|
||||||
})
|
|
||||||
1
migrations/env.py
Symbolic link
1
migrations/env.py
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
env.py.DEBUG
|
||||||
27
migrations/env.py.NODEBUG
Normal file
27
migrations/env.py.NODEBUG
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
from importlib import import_module
|
||||||
|
from alembic import context
|
||||||
|
from alchemical.alembic.env import run_migrations
|
||||||
|
|
||||||
|
# this is the Alembic Config object, which provides
|
||||||
|
# access to the values within the .ini file in use.
|
||||||
|
config = context.config
|
||||||
|
|
||||||
|
# import the application's Alchemical instance
|
||||||
|
try:
|
||||||
|
import_mod, db_name = config.get_main_option('alchemical_db', '').split(
|
||||||
|
':')
|
||||||
|
db = getattr(import_module(import_mod), db_name)
|
||||||
|
except (ModuleNotFoundError, AttributeError):
|
||||||
|
raise ValueError(
|
||||||
|
'Could not import the Alchemical database instance. '
|
||||||
|
'Ensure that the alchemical_db setting in alembic.ini is correct.'
|
||||||
|
)
|
||||||
|
|
||||||
|
# run the migration engine
|
||||||
|
# The dictionary provided as second argument includes options to pass to the
|
||||||
|
# Alembic context. For details on what other options are available, see
|
||||||
|
# https://alembic.sqlalchemy.org/en/latest/autogenerate.html
|
||||||
|
run_migrations(db, {
|
||||||
|
'render_as_batch': True,
|
||||||
|
'compare_type': True,
|
||||||
|
})
|
||||||
@ -1,52 +0,0 @@
|
|||||||
"""Add data for query playlists
|
|
||||||
|
|
||||||
Revision ID: 014f2d4c88a5
|
|
||||||
Revises: 33c04e3c12c8
|
|
||||||
Create Date: 2024-12-30 14:23:36.924478
|
|
||||||
|
|
||||||
"""
|
|
||||||
from alembic import op
|
|
||||||
import sqlalchemy as sa
|
|
||||||
|
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
|
||||||
revision = '014f2d4c88a5'
|
|
||||||
down_revision = '33c04e3c12c8'
|
|
||||||
branch_labels = None
|
|
||||||
depends_on = None
|
|
||||||
|
|
||||||
|
|
||||||
def upgrade(engine_name: str) -> None:
|
|
||||||
globals()["upgrade_%s" % engine_name]()
|
|
||||||
|
|
||||||
|
|
||||||
def downgrade(engine_name: str) -> None:
|
|
||||||
globals()["downgrade_%s" % engine_name]()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def upgrade_() -> None:
|
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
|
||||||
op.create_table('queries',
|
|
||||||
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
|
|
||||||
sa.Column('query', sa.String(length=2048), nullable=False),
|
|
||||||
sa.Column('playlist_id', sa.Integer(), nullable=False),
|
|
||||||
sa.ForeignKeyConstraint(['playlist_id'], ['playlists.id'], ),
|
|
||||||
sa.PrimaryKeyConstraint('id')
|
|
||||||
)
|
|
||||||
with op.batch_alter_table('queries', schema=None) as batch_op:
|
|
||||||
batch_op.create_index(batch_op.f('ix_queries_playlist_id'), ['playlist_id'], unique=False)
|
|
||||||
|
|
||||||
# ### end Alembic commands ###
|
|
||||||
|
|
||||||
|
|
||||||
def downgrade_() -> None:
|
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
|
||||||
with op.batch_alter_table('queries', schema=None) as batch_op:
|
|
||||||
batch_op.drop_index(batch_op.f('ix_queries_playlist_id'))
|
|
||||||
|
|
||||||
op.drop_table('queries')
|
|
||||||
# ### end Alembic commands ###
|
|
||||||
|
|
||||||
@ -0,0 +1,68 @@
|
|||||||
|
"""Index for notesolours substring
|
||||||
|
|
||||||
|
Revision ID: c76e865ccb85
|
||||||
|
Revises: 33c04e3c12c8
|
||||||
|
Create Date: 2025-02-07 18:21:01.760057
|
||||||
|
|
||||||
|
"""
|
||||||
|
from alembic import op
|
||||||
|
import sqlalchemy as sa
|
||||||
|
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision = 'c76e865ccb85'
|
||||||
|
down_revision = '33c04e3c12c8'
|
||||||
|
branch_labels = None
|
||||||
|
depends_on = None
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade(engine_name: str) -> None:
|
||||||
|
globals()["upgrade_%s" % engine_name]()
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade(engine_name: str) -> None:
|
||||||
|
globals()["downgrade_%s" % engine_name]()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade_() -> None:
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
with op.batch_alter_table('notecolours', schema=None) as batch_op:
|
||||||
|
batch_op.create_index(batch_op.f('ix_notecolours_substring'), ['substring'], unique=False)
|
||||||
|
|
||||||
|
with op.batch_alter_table('playdates', schema=None) as batch_op:
|
||||||
|
batch_op.drop_constraint('fk_playdates_track_id_tracks', type_='foreignkey')
|
||||||
|
batch_op.create_foreign_key(None, 'tracks', ['track_id'], ['id'], ondelete='CASCADE')
|
||||||
|
|
||||||
|
with op.batch_alter_table('playlist_rows', schema=None) as batch_op:
|
||||||
|
batch_op.drop_constraint('playlist_rows_ibfk_1', type_='foreignkey')
|
||||||
|
batch_op.create_foreign_key(None, 'tracks', ['track_id'], ['id'], ondelete='CASCADE')
|
||||||
|
|
||||||
|
with op.batch_alter_table('queries', schema=None) as batch_op:
|
||||||
|
batch_op.drop_constraint('fk_queries_playlist_id_playlists', type_='foreignkey')
|
||||||
|
batch_op.create_foreign_key(None, 'playlists', ['playlist_id'], ['id'], ondelete='CASCADE')
|
||||||
|
|
||||||
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade_() -> None:
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
with op.batch_alter_table('queries', schema=None) as batch_op:
|
||||||
|
batch_op.drop_constraint(None, type_='foreignkey')
|
||||||
|
batch_op.create_foreign_key('fk_queries_playlist_id_playlists', 'playlists', ['playlist_id'], ['id'])
|
||||||
|
|
||||||
|
with op.batch_alter_table('playlist_rows', schema=None) as batch_op:
|
||||||
|
batch_op.drop_constraint(None, type_='foreignkey')
|
||||||
|
batch_op.create_foreign_key('playlist_rows_ibfk_1', 'tracks', ['track_id'], ['id'])
|
||||||
|
|
||||||
|
with op.batch_alter_table('playdates', schema=None) as batch_op:
|
||||||
|
batch_op.drop_constraint(None, type_='foreignkey')
|
||||||
|
batch_op.create_foreign_key('fk_playdates_track_id_tracks', 'tracks', ['track_id'], ['id'])
|
||||||
|
|
||||||
|
with op.batch_alter_table('notecolours', schema=None) as batch_op:
|
||||||
|
batch_op.drop_index(batch_op.f('ix_notecolours_substring'))
|
||||||
|
|
||||||
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
Loading…
Reference in New Issue
Block a user