models.py moved to models/models.py

refactor all imports
This commit is contained in:
2025-07-15 10:45:56 +00:00
parent 661d25d70c
commit f37744b31e
29 changed files with 379 additions and 462 deletions

View File

@@ -0,0 +1,109 @@
"""initial
Revision ID: 3d15c3cac7b6
Revises:
Create Date: 2025-07-15 09:43:16.209294
"""
from typing import Sequence, Union
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision: str = '3d15c3cac7b6'
down_revision: Union[str, None] = None
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! ###
op.create_table('client_groups',
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
sa.Column('name', sa.String(length=100), nullable=False),
sa.Column('created_at', sa.TIMESTAMP(timezone=True), server_default=sa.text('CURRENT_TIMESTAMP'), nullable=True),
sa.Column('is_active', sa.Boolean(), nullable=False),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('name')
)
op.create_table('event_media',
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
sa.Column('media_type', sa.Enum('pdf', 'ppt', 'pptx', 'odp', 'mp4', 'avi', 'mkv', 'mov', 'wmv', 'flv', 'webm', 'mpg', 'mpeg', 'ogv', 'jpg', 'jpeg', 'png', 'gif', 'bmp', 'tiff', 'svg', 'html', name='mediatype'), nullable=False),
sa.Column('url', sa.String(length=255), nullable=False),
sa.Column('file_path', sa.String(length=255), nullable=True),
sa.Column('message_content', sa.Text(), nullable=True),
sa.PrimaryKeyConstraint('id')
)
op.create_table('users',
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
sa.Column('username', sa.String(length=50), nullable=False),
sa.Column('password_hash', sa.String(length=128), nullable=False),
sa.Column('role', sa.Enum('user', 'admin', 'superadmin', name='userrole'), nullable=False),
sa.Column('is_active', sa.Boolean(), nullable=False),
sa.Column('created_at', sa.TIMESTAMP(timezone=True), server_default=sa.text('CURRENT_TIMESTAMP'), nullable=True),
sa.Column('updated_at', sa.TIMESTAMP(timezone=True), server_default=sa.text('CURRENT_TIMESTAMP'), nullable=True),
sa.PrimaryKeyConstraint('id')
)
op.create_index(op.f('ix_users_username'), 'users', ['username'], unique=True)
op.create_table('clients',
sa.Column('uuid', sa.String(length=36), nullable=False),
sa.Column('hardware_hash', sa.String(length=64), nullable=False),
sa.Column('location', sa.String(length=100), nullable=True),
sa.Column('ip_address', sa.String(length=45), nullable=True),
sa.Column('registration_time', sa.TIMESTAMP(timezone=True), server_default=sa.text('CURRENT_TIMESTAMP'), nullable=False),
sa.Column('last_alive', sa.TIMESTAMP(timezone=True), server_default=sa.text('CURRENT_TIMESTAMP'), nullable=False),
sa.Column('is_active', sa.Boolean(), nullable=False),
sa.Column('group_id', sa.Integer(), nullable=False),
sa.ForeignKeyConstraint(['group_id'], ['client_groups.id'], ),
sa.PrimaryKeyConstraint('uuid')
)
op.create_index(op.f('ix_clients_hardware_hash'), 'clients', ['hardware_hash'], unique=False)
op.create_index(op.f('ix_clients_ip_address'), 'clients', ['ip_address'], unique=False)
op.create_table('events',
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
sa.Column('group_id', sa.Integer(), nullable=False),
sa.Column('title', sa.String(length=100), nullable=False),
sa.Column('description', sa.Text(), nullable=True),
sa.Column('start', sa.TIMESTAMP(timezone=True), nullable=False),
sa.Column('end', sa.TIMESTAMP(timezone=True), nullable=False),
sa.Column('event_type', sa.Enum('presentation', 'website', 'video', 'message', 'other', 'webuntis', name='eventtype'), nullable=False),
sa.Column('event_media_id', sa.Integer(), nullable=True),
sa.Column('autoplay', sa.Boolean(), nullable=True),
sa.Column('loop', sa.Boolean(), nullable=True),
sa.Column('volume', sa.Float(), nullable=True),
sa.Column('slideshow_interval', sa.Integer(), nullable=True),
sa.Column('created_at', sa.TIMESTAMP(timezone=True), server_default=sa.text('CURRENT_TIMESTAMP'), nullable=True),
sa.Column('updated_at', sa.TIMESTAMP(timezone=True), server_default=sa.text('CURRENT_TIMESTAMP'), nullable=True),
sa.Column('created_by', sa.Integer(), nullable=False),
sa.Column('updated_by', sa.Integer(), nullable=True),
sa.Column('is_active', sa.Boolean(), nullable=False),
sa.ForeignKeyConstraint(['created_by'], ['users.id'], ),
sa.ForeignKeyConstraint(['event_media_id'], ['event_media.id'], ),
sa.ForeignKeyConstraint(['group_id'], ['client_groups.id'], ),
sa.ForeignKeyConstraint(['updated_by'], ['users.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_index(op.f('ix_events_end'), 'events', ['end'], unique=False)
op.create_index(op.f('ix_events_group_id'), 'events', ['group_id'], unique=False)
op.create_index(op.f('ix_events_start'), 'events', ['start'], unique=False)
# ### end Alembic commands ###
def downgrade() -> None:
"""Downgrade schema."""
# ### commands auto generated by Alembic - please adjust! ###
op.drop_index(op.f('ix_events_start'), table_name='events')
op.drop_index(op.f('ix_events_group_id'), table_name='events')
op.drop_index(op.f('ix_events_end'), table_name='events')
op.drop_table('events')
op.drop_index(op.f('ix_clients_ip_address'), table_name='clients')
op.drop_index(op.f('ix_clients_hardware_hash'), table_name='clients')
op.drop_table('clients')
op.drop_index(op.f('ix_users_username'), table_name='users')
op.drop_table('users')
op.drop_table('event_media')
op.drop_table('client_groups')
# ### end Alembic commands ###

View File

@@ -1,57 +0,0 @@
"""Add client_groups table and group_id to clients
Revision ID: 8a45ec34f84d
Revises: c1178d5fa549
Create Date: 2025-06-26 18:40:10.988281
"""
from typing import Sequence, Union
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision: str = '8a45ec34f84d'
down_revision: Union[str, None] = 'c1178d5fa549'
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
def upgrade() -> None:
"""Upgrade schema."""
# 1. Neue Tabelle anlegen
op.create_table(
'client_groups',
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
sa.Column('name', sa.String(length=100), nullable=False),
sa.Column('created_at', sa.TIMESTAMP(timezone=True),
server_default=sa.text('CURRENT_TIMESTAMP'), nullable=True),
sa.Column('is_active', sa.Boolean(), nullable=False),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('name')
)
# 2. Gruppe "Nicht zugeordnet" mit id=0 anlegen
op.execute(
"INSERT INTO client_groups (id, name, is_active) VALUES (0, 'Nicht zugeordnet', true)")
# 3. Spalte group_id mit Default 0 hinzufügen
op.add_column('clients', sa.Column('group_id', sa.Integer(),
nullable=False, server_default='0'))
# 4. Für alle bestehenden Clients group_id auf 0 setzen (optional, falls Daten vorhanden)
op.execute("UPDATE clients SET group_id = 0 WHERE group_id IS NULL")
# 5. Foreign Key Constraint setzen
op.create_foreign_key(None, 'clients', 'client_groups', [
'group_id'], ['id'])
# ### end Alembic commands ###
def downgrade() -> None:
"""Downgrade schema."""
# ### commands auto generated by Alembic - please adjust! ###
op.drop_constraint(None, 'clients', type_='foreignkey')
op.drop_column('clients', 'group_id')
op.drop_table('client_groups')
# ### end Alembic commands ###

View File

@@ -1,34 +0,0 @@
"""Update media_type enum for event_media
Revision ID: a0f3f9325e05
Revises: bb29b5524f5c
Create Date: 2025-07-05 07:49:37.696162
"""
from typing import Sequence, Union
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision: str = 'a0f3f9325e05'
down_revision: Union[str, None] = 'bb29b5524f5c'
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
def upgrade():
op.execute("""
ALTER TABLE event_media MODIFY COLUMN media_type ENUM(
'pdf','ppt','pptx','odp',
'mp4','avi','mkv','mov','wmv','flv','webm','mpg','mpeg','ogv',
'jpg','jpeg','png','gif','bmp','tiff','svg',
'html'
) NOT NULL;
""")
def downgrade() -> None:
"""Downgrade schema."""
pass

View File

@@ -1,46 +0,0 @@
"""Refactor EventMedia: move playback fields to events, add MediaType enum, remove order
Revision ID: bb29b5524f5c
Revises: fadba5bc526c
Create Date: 2025-07-05 05:13:31.837339
"""
from typing import Sequence, Union
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import mysql
# revision identifiers, used by Alembic.
revision: str = 'bb29b5524f5c'
down_revision: Union[str, None] = 'fadba5bc526c'
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! ###
op.drop_column('event_media', 'autoplay')
op.drop_column('event_media', 'order')
op.drop_column('event_media', 'loop')
op.drop_column('event_media', 'volume')
op.add_column('events', sa.Column('autoplay', sa.Boolean(), nullable=True))
op.add_column('events', sa.Column('loop', sa.Boolean(), nullable=True))
op.add_column('events', sa.Column('volume', sa.Float(), nullable=True))
op.add_column('events', sa.Column('slideshow_interval', sa.Integer(), nullable=True))
# ### end Alembic commands ###
def downgrade() -> None:
"""Downgrade schema."""
# ### commands auto generated by Alembic - please adjust! ###
op.drop_column('events', 'slideshow_interval')
op.drop_column('events', 'volume')
op.drop_column('events', 'loop')
op.drop_column('events', 'autoplay')
op.add_column('event_media', sa.Column('volume', mysql.FLOAT(), nullable=True))
op.add_column('event_media', sa.Column('loop', mysql.TINYINT(display_width=1), autoincrement=False, nullable=True))
op.add_column('event_media', sa.Column('order', mysql.INTEGER(display_width=11), autoincrement=False, nullable=True))
op.add_column('event_media', sa.Column('autoplay', mysql.TINYINT(display_width=1), autoincrement=False, nullable=True))
# ### end Alembic commands ###

View File

@@ -1,88 +0,0 @@
"""event_db
Revision ID: c1178d5fa549
Revises: f7dd3165f238
Create Date: 2025-06-08 12:29:28.366231
"""
from typing import Sequence, Union
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import mysql
# revision identifiers, used by Alembic.
revision: str = 'c1178d5fa549'
down_revision: Union[str, None] = 'f7dd3165f238'
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! ###
op.create_table('events',
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
sa.Column('client_uuid', sa.String(length=36), nullable=False),
sa.Column('title', sa.String(length=100), nullable=False),
sa.Column('description', sa.Text(), nullable=True),
sa.Column('start', sa.TIMESTAMP(timezone=True), nullable=False),
sa.Column('end', sa.TIMESTAMP(timezone=True), nullable=False),
sa.Column('event_type', sa.Enum('presentation', 'website', 'video', 'message', 'other', 'webuntis', name='eventtype'), nullable=False),
sa.Column('created_at', sa.TIMESTAMP(timezone=True), server_default=sa.text('CURRENT_TIMESTAMP'), nullable=True),
sa.Column('updated_at', sa.TIMESTAMP(timezone=True), server_default=sa.text('CURRENT_TIMESTAMP'), nullable=True),
sa.Column('created_by', sa.Integer(), nullable=False),
sa.Column('updated_by', sa.Integer(), nullable=True),
sa.Column('is_active', sa.Boolean(), nullable=False),
sa.ForeignKeyConstraint(['client_uuid'], ['clients.uuid'], ),
sa.ForeignKeyConstraint(['created_by'], ['users.id'], ),
sa.ForeignKeyConstraint(['updated_by'], ['users.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_index(op.f('ix_events_client_uuid'), 'events', ['client_uuid'], unique=False)
op.create_index(op.f('ix_events_end'), 'events', ['end'], unique=False)
op.create_index(op.f('ix_events_start'), 'events', ['start'], unique=False)
op.create_table('event_media',
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
sa.Column('event_id', sa.Integer(), nullable=False),
sa.Column('media_type', sa.Enum('presentation', 'website', 'video', 'message', 'other', 'webuntis', name='eventtype'), nullable=False),
sa.Column('url', sa.String(length=255), nullable=False),
sa.Column('order', sa.Integer(), nullable=True),
sa.Column('autoplay', sa.Boolean(), nullable=True),
sa.Column('loop', sa.Boolean(), nullable=True),
sa.Column('volume', sa.Float(), nullable=True),
sa.ForeignKeyConstraint(['event_id'], ['events.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.add_column('clients', sa.Column('is_active', sa.Boolean(), nullable=False))
op.create_index(op.f('ix_clients_hardware_hash'), 'clients', ['hardware_hash'], unique=False)
op.create_index(op.f('ix_clients_ip_address'), 'clients', ['ip_address'], unique=False)
op.add_column('users', sa.Column('is_active', sa.Boolean(), nullable=False))
op.alter_column('users', 'password_hash',
existing_type=mysql.VARCHAR(length=60),
type_=sa.String(length=128),
existing_nullable=False)
op.drop_index(op.f('username'), table_name='users')
op.create_index(op.f('ix_users_username'), 'users', ['username'], unique=True)
# ### end Alembic commands ###
def downgrade() -> None:
"""Downgrade schema."""
# ### commands auto generated by Alembic - please adjust! ###
op.drop_index(op.f('ix_users_username'), table_name='users')
op.create_index(op.f('username'), 'users', ['username'], unique=True)
op.alter_column('users', 'password_hash',
existing_type=sa.String(length=128),
type_=mysql.VARCHAR(length=60),
existing_nullable=False)
op.drop_column('users', 'is_active')
op.drop_index(op.f('ix_clients_ip_address'), table_name='clients')
op.drop_index(op.f('ix_clients_hardware_hash'), table_name='clients')
op.drop_column('clients', 'is_active')
op.drop_table('event_media')
op.drop_index(op.f('ix_events_start'), table_name='events')
op.drop_index(op.f('ix_events_end'), table_name='events')
op.drop_index(op.f('ix_events_client_uuid'), table_name='events')
op.drop_table('events')
# ### end Alembic commands ###

View File

@@ -1,46 +0,0 @@
"""Refactor Event/EventMedia relation
Revision ID: c571e4214528
Revises: d490cbfdea65
Create Date: 2025-07-04 06:08:57.004474
"""
from typing import Sequence, Union
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import mysql
# revision identifiers, used by Alembic.
revision: str = 'c571e4214528'
down_revision: Union[str, None] = 'd490cbfdea65'
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! ###
op.create_foreign_key(None, 'clients', 'client_groups', ['group_id'], ['id'])
op.drop_constraint(op.f('event_media_ibfk_1'), 'event_media', type_='foreignkey')
op.drop_column('event_media', 'event_id')
op.add_column('events', sa.Column('event_media_id', sa.Integer(), nullable=True))
op.alter_column('events', 'group_id',
existing_type=mysql.INTEGER(display_width=11),
nullable=False)
op.create_foreign_key(None, 'events', 'event_media', ['event_media_id'], ['id'])
# ### end Alembic commands ###
def downgrade() -> None:
"""Downgrade schema."""
# ### commands auto generated by Alembic - please adjust! ###
op.drop_constraint(None, 'events', type_='foreignkey')
op.alter_column('events', 'group_id',
existing_type=mysql.INTEGER(display_width=11),
nullable=True)
op.drop_column('events', 'event_media_id')
op.add_column('event_media', sa.Column('event_id', mysql.INTEGER(display_width=11), autoincrement=False, nullable=False))
op.create_foreign_key(op.f('event_media_ibfk_1'), 'event_media', 'events', ['event_id'], ['id'])
op.drop_constraint(None, 'clients', type_='foreignkey')
# ### end Alembic commands ###

View File

@@ -1,91 +0,0 @@
"""Migrate events to use group_id instead of client_uuid
Revision ID: d490cbfdea65
Revises: 8a45ec34f84d
Create Date: 2025-06-30 19:16:29.138440
ACHTUNG:
Ein Downgrade dieser Migration ist NICHT verlustfrei möglich, wenn mehrere Clients einer Gruppe zugeordnet sind.
Beim Downgrade wird jedem Event willkürlich ein (der erste gefundene) Client der Gruppe zugeordnet.
Die ursprüngliche Zuordnung von Events zu Clients kann dadurch NICHT wiederhergestellt werden!
"""
from typing import Sequence, Union
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision: str = 'd490cbfdea65'
down_revision: Union[str, None] = '8a45ec34f84d'
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
def upgrade() -> None:
"""Upgrade schema."""
# 1. Neue Spalte group_id (vorübergehend nullable)
op.add_column('events', sa.Column('group_id', sa.Integer(), nullable=True))
op.create_foreign_key(
'fk_events_group_id_client_groups',
'events', 'client_groups',
['group_id'], ['id']
)
op.create_index('ix_events_group_id', 'events', ['group_id'])
# 2. group_id für alle Events anhand client_uuid setzen
op.execute("""
UPDATE events
SET group_id = (
SELECT group_id FROM clients WHERE clients.uuid = events.client_uuid
)
""")
# 3. client_uuid entfernen
op.drop_constraint('events_ibfk_1', 'events',
type_='foreignkey') # Name ggf. anpassen!
# Name ggf. anpassen!
op.drop_index('ix_events_client_uuid', table_name='events')
op.drop_column('events', 'client_uuid')
# 4. group_id auf NOT NULL setzen
op.alter_column(
'events',
'group_id',
existing_type=sa.Integer(),
nullable=False
)
def downgrade() -> None:
"""Downgrade schema.
ACHTUNG:
Ein Downgrade ist nicht verlustfrei möglich, wenn mehrere Clients pro Gruppe existieren.
Es wird jeweils ein beliebiger (erster) Client der Gruppe für die Zuordnung gewählt.
"""
# 1. client_uuid wieder hinzufügen
op.add_column('events', sa.Column(
'client_uuid', sa.String(length=36), nullable=True))
op.create_foreign_key(
'fk_events_client_uuid_clients',
'events', 'clients',
['client_uuid'], ['uuid']
)
op.create_index('ix_events_client_uuid', 'events', ['client_uuid'])
# 2. client_uuid anhand group_id zurücksetzen (nur möglich, wenn 1:1-Beziehung!)
# Falls mehrere Clients pro Gruppe: Datenverlust möglich!
# Hier ggf. eine Strategie überlegen oder leerlassen.
op.execute("""
UPDATE events
SET client_uuid = (
SELECT uuid FROM clients WHERE clients.group_id = events.group_id LIMIT 1
)
""")
# 3. group_id entfernen
op.drop_constraint('fk_events_group_id_client_groups',
'events', type_='foreignkey')
op.drop_index('ix_events_group_id', table_name='events')
op.drop_column('events', 'group_id')

View File

@@ -1,32 +0,0 @@
"""initial
Revision ID: f7dd3165f238
Revises:
Create Date: 2025-06-08 12:25:27.174339
"""
from typing import Sequence, Union
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision: str = 'f7dd3165f238'
down_revision: Union[str, None] = None
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! ###
pass
# ### end Alembic commands ###
def downgrade() -> None:
"""Downgrade schema."""
# ### commands auto generated by Alembic - please adjust! ###
pass
# ### end Alembic commands ###

View File

@@ -1,34 +0,0 @@
"""Add Filepath and Message-Content to EventMedia
Revision ID: fadba5bc526c
Revises: c571e4214528
Create Date: 2025-07-05 04:46:13.542887
"""
from typing import Sequence, Union
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision: str = 'fadba5bc526c'
down_revision: Union[str, None] = 'c571e4214528'
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! ###
op.add_column('event_media', sa.Column('file_path', sa.String(length=255), nullable=True))
op.add_column('event_media', sa.Column('message_content', sa.Text(), nullable=True))
# ### end Alembic commands ###
def downgrade() -> None:
"""Downgrade schema."""
# ### commands auto generated by Alembic - please adjust! ###
op.drop_column('event_media', 'message_content')
op.drop_column('event_media', 'file_path')
# ### end Alembic commands ###