better migrations

This commit is contained in:
2025-06-04 09:31:12 +02:00
parent 9dd4ac5863
commit b580bb2db3
48 changed files with 120 additions and 124 deletions

5
.gitignore vendored
View File

@@ -26,4 +26,7 @@ logs/
*.log
# Testing
coverage/
coverage/
# Python cache
__pycache__/

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1,61 +0,0 @@
import os
import sys
from pathlib import Path
# Add the parent directory to Python path so we can import from root
sys.path.append(str(Path(__file__).parent.parent))
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from extensions import db
from sqlalchemy import text
def upgrade():
# Create events table
with db.engine.connect() as conn:
conn.execute(text('''
CREATE TABLE IF NOT EXISTS events (
id SERIAL PRIMARY KEY,
event_type VARCHAR(50) NOT NULL,
user_id INTEGER NOT NULL REFERENCES "user" (id),
timestamp TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
details JSONB,
ip_address VARCHAR(45),
user_agent VARCHAR(255)
);
-- Create index on event_type for faster filtering
CREATE INDEX IF NOT EXISTS idx_events_event_type ON events(event_type);
-- Create index on timestamp for faster date-based queries
CREATE INDEX IF NOT EXISTS idx_events_timestamp ON events(timestamp);
-- Create index on user_id for faster user-based queries
CREATE INDEX IF NOT EXISTS idx_events_user_id ON events(user_id);
'''))
conn.commit()
def downgrade():
# Drop events table and its indexes
with db.engine.connect() as conn:
conn.execute(text('''
DROP INDEX IF EXISTS idx_events_event_type;
DROP INDEX IF EXISTS idx_events_timestamp;
DROP INDEX IF EXISTS idx_events_user_id;
DROP TABLE IF EXISTS events;
'''))
conn.commit()
if __name__ == '__main__':
app = Flask(__name__)
# Use the same database configuration as in app.py
app.config['SQLALCHEMY_DATABASE_URI'] = os.getenv('DATABASE_URL', 'postgresql://postgres:1253@localhost:5432/docupulse')
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
print("Connecting to database...")
db.init_app(app)
with app.app_context():
upgrade()

View File

@@ -1,61 +0,0 @@
import os
import sys
from pathlib import Path
# Add the parent directory to Python path so we can import from root
sys.path.append(str(Path(__file__).parent.parent))
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from extensions import db
from sqlalchemy import text
def upgrade():
# Create notifs table
with db.engine.connect() as conn:
conn.execute(text('''
CREATE TABLE IF NOT EXISTS notifs (
id SERIAL PRIMARY KEY,
notif_type VARCHAR(50) NOT NULL,
user_id INTEGER NOT NULL REFERENCES "user" (id),
sender_id INTEGER REFERENCES "user" (id),
timestamp TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
read BOOLEAN NOT NULL DEFAULT FALSE,
details JSONB
);
-- Create indexes for faster queries
CREATE INDEX IF NOT EXISTS idx_notifs_notif_type ON notifs(notif_type);
CREATE INDEX IF NOT EXISTS idx_notifs_timestamp ON notifs(timestamp);
CREATE INDEX IF NOT EXISTS idx_notifs_user_id ON notifs(user_id);
CREATE INDEX IF NOT EXISTS idx_notifs_sender_id ON notifs(sender_id);
CREATE INDEX IF NOT EXISTS idx_notifs_read ON notifs(read);
'''))
conn.commit()
def downgrade():
# Drop notifs table and its indexes
with db.engine.connect() as conn:
conn.execute(text('''
DROP INDEX IF EXISTS idx_notifs_notif_type;
DROP INDEX IF EXISTS idx_notifs_timestamp;
DROP INDEX IF EXISTS idx_notifs_user_id;
DROP INDEX IF EXISTS idx_notifs_sender_id;
DROP INDEX IF EXISTS idx_notifs_read;
DROP TABLE IF EXISTS notifs;
'''))
conn.commit()
if __name__ == '__main__':
app = Flask(__name__)
# Use the same database configuration as in app.py
app.config['SQLALCHEMY_DATABASE_URI'] = os.getenv('DATABASE_URL', 'postgresql://postgres:1253@localhost:5432/docupulse')
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
print("Connecting to database...")
db.init_app(app)
with app.app_context():
upgrade()

View File

@@ -0,0 +1,42 @@
"""create events table
Revision ID: add_events_table
Revises: f18735338888
Create Date: 2024-03-19 10:00:00.000000
"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy import inspect
# revision identifiers, used by Alembic.
revision = 'add_events_table'
down_revision = 'f18735338888'
branch_labels = None
depends_on = None
def upgrade():
conn = op.get_bind()
inspector = inspect(conn)
tables = inspector.get_table_names()
if 'events' not in tables:
op.create_table(
'events',
sa.Column('id', sa.Integer, primary_key=True),
sa.Column('event_type', sa.String(50), nullable=False),
sa.Column('user_id', sa.Integer, sa.ForeignKey('user.id'), nullable=True),
sa.Column('timestamp', sa.DateTime, nullable=False),
sa.Column('details', sa.JSON),
sa.Column('ip_address', sa.String(45)),
sa.Column('user_agent', sa.String(255)),
)
op.create_index('idx_events_event_type', 'events', ['event_type'])
op.create_index('idx_events_timestamp', 'events', ['timestamp'])
op.create_index('idx_events_user_id', 'events', ['user_id'])
def downgrade():
op.drop_index('idx_events_event_type', table_name='events')
op.drop_index('idx_events_timestamp', table_name='events')
op.drop_index('idx_events_user_id', table_name='events')
op.drop_table('events')

View File

@@ -0,0 +1,46 @@
"""create notifs table
Revision ID: add_notifs_table
Revises: add_events_table
Create Date: 2024-03-19 10:00:00.000000
"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy import inspect
# revision identifiers, used by Alembic.
revision = 'add_notifs_table'
down_revision = 'add_events_table'
branch_labels = None
depends_on = None
def upgrade():
conn = op.get_bind()
inspector = inspect(conn)
tables = inspector.get_table_names()
if 'notifs' not in tables:
op.create_table(
'notifs',
sa.Column('id', sa.Integer, primary_key=True),
sa.Column('notif_type', sa.String(50), nullable=False),
sa.Column('user_id', sa.Integer, sa.ForeignKey('user.id'), nullable=False),
sa.Column('sender_id', sa.Integer, sa.ForeignKey('user.id'), nullable=True),
sa.Column('timestamp', sa.DateTime, nullable=False),
sa.Column('read', sa.Boolean, nullable=False, default=False),
sa.Column('details', sa.JSON),
)
op.create_index('idx_notifs_notif_type', 'notifs', ['notif_type'])
op.create_index('idx_notifs_timestamp', 'notifs', ['timestamp'])
op.create_index('idx_notifs_user_id', 'notifs', ['user_id'])
op.create_index('idx_notifs_sender_id', 'notifs', ['sender_id'])
op.create_index('idx_notifs_read', 'notifs', ['read'])
def downgrade():
op.drop_index('idx_notifs_notif_type', table_name='notifs')
op.drop_index('idx_notifs_timestamp', table_name='notifs')
op.drop_index('idx_notifs_user_id', table_name='notifs')
op.drop_index('idx_notifs_sender_id', table_name='notifs')
op.drop_index('idx_notifs_read', table_name='notifs')
op.drop_table('notifs')

View File

@@ -0,0 +1,27 @@
"""make events user_id nullable
Revision ID: make_events_user_id_nullable
Revises: f18735338888
Create Date: 2024-03-19 10:00:00.000000
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = 'make_events_user_id_nullable'
down_revision = 'f18735338888' # This should be the latest migration
branch_labels = None
depends_on = None
def upgrade():
# Make user_id nullable in events table
op.alter_column('events', 'user_id',
existing_type=sa.Integer(),
nullable=True)
def downgrade():
# Make user_id non-nullable again
op.alter_column('events', 'user_id',
existing_type=sa.Integer(),
nullable=False)

View File

@@ -284,7 +284,7 @@ class Event(db.Model):
__tablename__ = 'events'
id = db.Column(db.Integer, primary_key=True)
event_type = db.Column(db.String(50), nullable=False)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=True)
timestamp = db.Column(db.DateTime, default=datetime.utcnow, nullable=False)
details = db.Column(db.JSON) # Store additional event-specific data
ip_address = db.Column(db.String(45)) # IPv6 addresses can be up to 45 chars