mirror of https://github.com/Aidaho12/haproxy-wi
v8.2.0: Add database migration framework and initial migrations
Introduce migration management tools using Peewee's migrate module. Add scripts for migration creation, application, rollback, and listing. Include initial batch of database migrations for schema and data changes.master
parent
d268fc4f40
commit
b1bec4ec06
|
@ -20,11 +20,12 @@ scheduler.start()
|
|||
jwt = JWTManager(app)
|
||||
|
||||
from app.modules.db.db_model import create_tables
|
||||
from app.create_db import default_values, update_all
|
||||
from app.create_db import default_values
|
||||
from app.modules.db.migration_manager import migrate
|
||||
|
||||
create_tables()
|
||||
default_values()
|
||||
update_all()
|
||||
migrate()
|
||||
|
||||
set_correct_owner('/var/lib/roxy-wi')
|
||||
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
#!/usr/bin/env python3
|
||||
import argparse
|
||||
import sys
|
||||
import os
|
||||
|
||||
# Add the parent directory to the path so we can import the app modules
|
||||
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
|
||||
|
||||
from app.modules.db.migration_manager import create_migrations_table, migrate, rollback, create_migration, list_migrations
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description='Database migration tool')
|
||||
subparsers = parser.add_subparsers(dest='command', help='Command to run')
|
||||
|
||||
# Create migration command
|
||||
create_parser = subparsers.add_parser('create', help='Create a new migration')
|
||||
create_parser.add_argument('name', help='Name of the migration')
|
||||
|
||||
# Migrate command
|
||||
subparsers.add_parser('migrate', help='Apply pending migrations')
|
||||
|
||||
# Rollback command
|
||||
rollback_parser = subparsers.add_parser('rollback', help='Rollback migrations')
|
||||
rollback_parser.add_argument('--steps', type=int, default=1, help='Number of migrations to roll back')
|
||||
|
||||
# Initialize command
|
||||
subparsers.add_parser('init', help='Initialize the migrations table')
|
||||
|
||||
# list command
|
||||
subparsers.add_parser('list', help='List all migrations and their status')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.command == 'create':
|
||||
filename = create_migration(args.name)
|
||||
print(f"Created migration file: {filename}")
|
||||
elif args.command == 'migrate':
|
||||
success = migrate()
|
||||
if success:
|
||||
print("Migrations applied successfully")
|
||||
else:
|
||||
print("Error applying migrations")
|
||||
sys.exit(1)
|
||||
elif args.command == 'rollback':
|
||||
success = rollback(args.steps)
|
||||
if success:
|
||||
print(f"Rolled back {args.steps} migration(s) successfully")
|
||||
else:
|
||||
print("Error rolling back migrations")
|
||||
sys.exit(1)
|
||||
elif args.command == 'list':
|
||||
list_migrations()
|
||||
elif args.command == 'init':
|
||||
create_migrations_table()
|
||||
print("Migrations table initialized")
|
||||
else:
|
||||
parser.print_help()
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
|
@ -1,6 +1,6 @@
|
|||
from datetime import datetime
|
||||
|
||||
from peewee import ForeignKeyField
|
||||
from peewee import ForeignKeyField,CharField, DateTimeField, AutoField
|
||||
from playhouse.migrate import *
|
||||
from playhouse.shortcuts import ReconnectMixin
|
||||
from playhouse.sqlite_ext import SqliteExtDatabase
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
#!/usr/bin/env python3
|
||||
import argparse
|
||||
import sys
|
||||
import os
|
||||
|
||||
# Add the parent directory to the path so we can import the app modules
|
||||
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '../../..')))
|
||||
|
||||
from app.modules.db.migration_manager import create_migrations_table, migrate, rollback, create_migration, list_migrations
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description='Database migration tool')
|
||||
subparsers = parser.add_subparsers(dest='command', help='Command to run')
|
||||
|
||||
# Create migration command
|
||||
create_parser = subparsers.add_parser('create', help='Create a new migration')
|
||||
create_parser.add_argument('name', help='Name of the migration')
|
||||
|
||||
# Migrate command
|
||||
migrate_parser = subparsers.add_parser('migrate', help='Apply pending migrations')
|
||||
|
||||
# Rollback command
|
||||
rollback_parser = subparsers.add_parser('rollback', help='Rollback migrations')
|
||||
rollback_parser.add_argument('--steps', type=int, default=1, help='Number of migrations to roll back')
|
||||
|
||||
# Initialize command
|
||||
init_parser = subparsers.add_parser('init', help='Initialize the migrations table')
|
||||
|
||||
# list command
|
||||
subparsers.add_parser('list', help='List all migrations and their status')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.command == 'create':
|
||||
filename = create_migration(args.name)
|
||||
print(f"Created migration file: {filename}")
|
||||
elif args.command == 'migrate':
|
||||
success = migrate()
|
||||
if success:
|
||||
print("Migrations applied successfully")
|
||||
else:
|
||||
print("Error applying migrations")
|
||||
sys.exit(1)
|
||||
elif args.command == 'rollback':
|
||||
success = rollback(args.steps)
|
||||
if success:
|
||||
print(f"Rolled back {args.steps} migration(s) successfully")
|
||||
else:
|
||||
print("Error rolling back migrations")
|
||||
sys.exit(1)
|
||||
elif args.command == 'list':
|
||||
list_migrations()
|
||||
elif args.command == 'init':
|
||||
create_migrations_table()
|
||||
print("Migrations table initialized")
|
||||
else:
|
||||
parser.print_help()
|
||||
sys.exit(1)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
|
@ -0,0 +1,176 @@
|
|||
import os
|
||||
import importlib
|
||||
from datetime import datetime
|
||||
|
||||
from peewee import CharField, DateTimeField, AutoField
|
||||
from playhouse.migrate import *
|
||||
|
||||
from app.modules.db.db_model import BaseModel, connect
|
||||
|
||||
|
||||
# Define the Migration model to track applied migrations
|
||||
class Migration(BaseModel):
|
||||
id = AutoField()
|
||||
name = CharField(unique=True)
|
||||
applied_at = DateTimeField(default=datetime.now)
|
||||
|
||||
class Meta:
|
||||
table_name = 'migrations'
|
||||
|
||||
def create_migrations_table():
|
||||
"""Create the migrations table if it doesn't exist."""
|
||||
conn = connect()
|
||||
conn.create_tables([Migration], safe=True)
|
||||
|
||||
def get_migration_files():
|
||||
"""Get all migration files from the migrations directory."""
|
||||
migrations_dir = os.path.join(os.path.dirname(__file__), 'migrations')
|
||||
migration_files = []
|
||||
|
||||
for filename in os.listdir(migrations_dir):
|
||||
if filename.endswith('.py') and not filename.startswith('__'):
|
||||
migration_name = filename[:-3] # Remove .py extension
|
||||
migration_files.append(migration_name)
|
||||
|
||||
# Sort migrations by name (which should include a timestamp)
|
||||
migration_files.sort()
|
||||
return migration_files
|
||||
|
||||
def get_applied_migrations():
|
||||
"""Get all migrations that have been applied."""
|
||||
return [m.name for m in Migration.select(Migration.name)]
|
||||
|
||||
def apply_migration(migration_name):
|
||||
"""Apply a single migration."""
|
||||
try:
|
||||
# Import the migration module
|
||||
module = importlib.import_module(f'app.modules.db.migrations.{migration_name}')
|
||||
|
||||
# Apply the migration
|
||||
print(f"Applying migration: {migration_name}")
|
||||
module.up()
|
||||
|
||||
# Record the migration as applied
|
||||
Migration.create(name=migration_name)
|
||||
print(f"Migration applied: {migration_name}")
|
||||
return True
|
||||
except Exception as e:
|
||||
print("error: applying migration {migration_name}: {str(e)}")
|
||||
return False
|
||||
|
||||
def rollback_migration(migration_name):
|
||||
"""Rollback a single migration."""
|
||||
try:
|
||||
# Import the migration module
|
||||
module = importlib.import_module(f'app.modules.db.migrations.{migration_name}')
|
||||
|
||||
# Rollback the migration
|
||||
print(f"Rolling back migration: {migration_name}")
|
||||
module.down()
|
||||
|
||||
# Remove the migration record
|
||||
Migration.delete().where(Migration.name == migration_name).execute()
|
||||
print(f"Migration rolled back: {migration_name}")
|
||||
return True
|
||||
except Exception as e:
|
||||
print("error: rolling back migration {migration_name}: {str(e)}")
|
||||
return False
|
||||
|
||||
def migrate():
|
||||
"""Apply all pending migrations."""
|
||||
create_migrations_table()
|
||||
|
||||
# Get all migration files and applied migrations
|
||||
migration_files = get_migration_files()
|
||||
applied_migrations = get_applied_migrations()
|
||||
|
||||
# Determine which migrations need to be applied
|
||||
pending_migrations = [m for m in migration_files if m not in applied_migrations]
|
||||
|
||||
if not pending_migrations:
|
||||
print("No pending migrations to apply.")
|
||||
return True
|
||||
|
||||
# Apply pending migrations
|
||||
success = True
|
||||
for migration_name in pending_migrations:
|
||||
if not apply_migration(migration_name):
|
||||
success = False
|
||||
break
|
||||
|
||||
return success
|
||||
|
||||
def rollback(steps=1):
|
||||
"""Rollback the specified number of migrations."""
|
||||
create_migrations_table()
|
||||
|
||||
# Get applied migrations in reverse order (most recent first)
|
||||
applied_migrations = Migration.select().order_by(Migration.applied_at.desc())
|
||||
|
||||
if not applied_migrations:
|
||||
print("No migrations to roll back.")
|
||||
return True
|
||||
|
||||
# Rollback the specified number of migrations
|
||||
success = True
|
||||
for i, migration in enumerate(applied_migrations):
|
||||
if i >= steps:
|
||||
break
|
||||
|
||||
if not rollback_migration(migration.name):
|
||||
success = False
|
||||
break
|
||||
|
||||
return success
|
||||
|
||||
def create_migration(name):
|
||||
"""Create a new migration file."""
|
||||
timestamp = datetime.now().strftime('%Y%m%d%H%M%S')
|
||||
filename = f"{timestamp}_{name}.py"
|
||||
filepath = os.path.join(os.path.dirname(__file__), 'migrations', filename)
|
||||
|
||||
template = """from playhouse.migrate import *
|
||||
from app.modules.db.db_model import connect, mysql_enable
|
||||
|
||||
migrator = connect(get_migrator=1)
|
||||
|
||||
def up():
|
||||
\"\"\"Apply the migration.\"\"\"
|
||||
# Example:
|
||||
# migrate(
|
||||
# migrator.add_column('table_name', 'column_name', CharField(default='')),
|
||||
# )
|
||||
pass
|
||||
|
||||
def down():
|
||||
\"\"\"Roll back the migration.\"\"\"
|
||||
# Example:
|
||||
# migrate(
|
||||
# migrator.drop_column('table_name', 'column_name'),
|
||||
# )
|
||||
pass
|
||||
"""
|
||||
|
||||
with open(filepath, 'w') as f:
|
||||
f.write(template)
|
||||
|
||||
print(f"Created migration file: {filename}")
|
||||
return filename
|
||||
|
||||
|
||||
def list_migrations() -> None:
|
||||
"""
|
||||
List all migrations and their status.
|
||||
"""
|
||||
# Get all migration files
|
||||
migration_files = get_migration_files()
|
||||
|
||||
# Get applied migrations
|
||||
applied_migrations = get_applied_migrations()
|
||||
|
||||
# Print migrations
|
||||
print("Migrations:")
|
||||
for filename in migration_files:
|
||||
migration_name = filename.replace('.py', '')
|
||||
status = "Applied" if migration_name in applied_migrations else "Pending"
|
||||
print(f" {migration_name}: {status}")
|
|
@ -0,0 +1,19 @@
|
|||
from playhouse.migrate import *
|
||||
from app.modules.db.db_model import connect, Version
|
||||
|
||||
migrator = connect(get_migrator=1)
|
||||
|
||||
def up():
|
||||
"""Apply the migration."""
|
||||
# Insert version record with version '1.0'
|
||||
try:
|
||||
Version.insert(version='1.0').execute()
|
||||
print("Inserted version record with version '1.0'")
|
||||
except Exception as e:
|
||||
print(f"Error inserting version record: {e}")
|
||||
|
||||
def down():
|
||||
"""Roll back the migration."""
|
||||
# This is the initial migration, so rolling back would mean dropping all tables
|
||||
# This is dangerous and not recommended, so we'll just pass
|
||||
pass
|
|
@ -0,0 +1,24 @@
|
|||
from playhouse.migrate import *
|
||||
from app.modules.db.db_model import connect, User, UserGroups
|
||||
|
||||
migrator = connect(get_migrator=1)
|
||||
|
||||
def up():
|
||||
"""Apply the migration."""
|
||||
# This migration updates user groups
|
||||
# It inserts user_id and group_id from User table into UserGroups table
|
||||
try:
|
||||
UserGroups.insert_from(
|
||||
User.select(User.user_id, User.group_id), fields=[UserGroups.user_id, UserGroups.user_group_id]
|
||||
).on_conflict_ignore().execute()
|
||||
except Exception as e:
|
||||
if e.args[0] == 'duplicate column name: haproxy' or str(e) == '(1060, "Duplicate column name \'haproxy\'")':
|
||||
print('Migration already applied')
|
||||
else:
|
||||
raise e
|
||||
|
||||
def down():
|
||||
"""Roll back the migration."""
|
||||
# This migration adds data, not schema changes, so rolling back would mean deleting data
|
||||
# This is potentially dangerous, so we'll just pass
|
||||
pass
|
|
@ -0,0 +1,34 @@
|
|||
from playhouse.migrate import *
|
||||
from app.modules.db.db_model import connect, mysql_enable
|
||||
from peewee import IntegerField, SQL
|
||||
|
||||
migrator = connect(get_migrator=1)
|
||||
|
||||
def up():
|
||||
"""Apply the migration."""
|
||||
# This migration adds a use_src column to the ha_cluster_vips table
|
||||
try:
|
||||
if mysql_enable:
|
||||
migrate(
|
||||
migrator.add_column('ha_cluster_vips', 'use_src', IntegerField(default=0)),
|
||||
)
|
||||
else:
|
||||
migrate(
|
||||
migrator.add_column('ha_cluster_vips', 'use_src', IntegerField(constraints=[SQL('DEFAULT 0')])),
|
||||
)
|
||||
except Exception as e:
|
||||
if e.args[0] == 'duplicate column name: use_src' or str(e) == '(1060, "Duplicate column name \'use_src\'")':
|
||||
print('Column already exists')
|
||||
else:
|
||||
raise e
|
||||
|
||||
def down():
|
||||
"""Roll back the migration."""
|
||||
# This migration removes the use_src column from the ha_cluster_vips table
|
||||
try:
|
||||
migrate(
|
||||
migrator.drop_column('ha_cluster_vips', 'use_src'),
|
||||
)
|
||||
except Exception as e:
|
||||
print(f"Error rolling back migration: {str(e)}")
|
||||
raise e
|
|
@ -0,0 +1,32 @@
|
|||
from playhouse.migrate import *
|
||||
from app.modules.db.db_model import connect
|
||||
|
||||
migrator = connect(get_migrator=1)
|
||||
|
||||
def up():
|
||||
"""Apply the migration."""
|
||||
# This migration renames columns in the backups table
|
||||
try:
|
||||
migrate(
|
||||
migrator.rename_column('backups', 'cred', 'cred_id'),
|
||||
migrator.rename_column('backups', 'backup_type', 'type'),
|
||||
)
|
||||
except Exception as e:
|
||||
if e.args[0] == 'no such column: "cred"' or str(e) == '(1060, no such column: "cred")':
|
||||
print("Columns already renamed")
|
||||
elif e.args[0] == "'bool' object has no attribute 'sql'":
|
||||
print("Columns already renamed")
|
||||
else:
|
||||
raise e
|
||||
|
||||
def down():
|
||||
"""Roll back the migration."""
|
||||
# This migration renames columns back to their original names
|
||||
try:
|
||||
migrate(
|
||||
migrator.rename_column('backups', 'cred_id', 'cred'),
|
||||
migrator.rename_column('backups', 'type', 'backup_type'),
|
||||
)
|
||||
except Exception as e:
|
||||
print(f"Error rolling back migration: {str(e)}")
|
||||
raise e
|
|
@ -0,0 +1,66 @@
|
|||
from playhouse.migrate import *
|
||||
from app.modules.db.db_model import connect
|
||||
|
||||
migrator = connect(get_migrator=1)
|
||||
|
||||
def up():
|
||||
"""Apply the migration."""
|
||||
# This migration renames multiple columns across different tables
|
||||
try:
|
||||
migrate(
|
||||
migrator.rename_column('telegram', 'groups', 'group_id'),
|
||||
migrator.rename_column('slack', 'groups', 'group_id'),
|
||||
migrator.rename_column('mattermost', 'groups', 'group_id'),
|
||||
migrator.rename_column('pd', 'groups', 'group_id'),
|
||||
migrator.rename_column('servers', 'groups', 'group_id'),
|
||||
migrator.rename_column('udp_balancers', 'desc', 'description'),
|
||||
migrator.rename_column('ha_clusters', 'desc', 'description'),
|
||||
migrator.rename_column('cred', 'enable', 'key_enabled'),
|
||||
migrator.rename_column('cred', 'groups', 'group_id'),
|
||||
migrator.rename_column('servers', 'desc', 'description'),
|
||||
migrator.rename_column('servers', 'active', 'haproxy_active'),
|
||||
migrator.rename_column('servers', 'metrics', 'haproxy_metrics'),
|
||||
migrator.rename_column('servers', 'alert', 'haproxy_alert'),
|
||||
migrator.rename_column('servers', 'cred', 'cred_id'),
|
||||
migrator.rename_column('servers', 'enable', 'enabled'),
|
||||
migrator.rename_column('servers', 'groups', 'group_id'),
|
||||
migrator.rename_column('user', 'activeuser', 'enabled'),
|
||||
migrator.rename_column('user', 'groups', 'group_id'),
|
||||
migrator.rename_column('user', 'role', 'role_id'),
|
||||
)
|
||||
except Exception as e:
|
||||
if e.args[0] == 'no such column: "groups"' or str(e) == '(1060, no such column: "groups")':
|
||||
print("Columns already renamed")
|
||||
elif e.args[0] == "'bool' object has no attribute 'sql'":
|
||||
print("Columns already renamed")
|
||||
else:
|
||||
raise e
|
||||
|
||||
def down():
|
||||
"""Roll back the migration."""
|
||||
# This migration renames columns back to their original names
|
||||
try:
|
||||
migrate(
|
||||
migrator.rename_column('telegram', 'group_id', 'groups'),
|
||||
migrator.rename_column('slack', 'group_id', 'groups'),
|
||||
migrator.rename_column('mattermost', 'group_id', 'groups'),
|
||||
migrator.rename_column('pd', 'group_id', 'groups'),
|
||||
migrator.rename_column('servers', 'group_id', 'groups'),
|
||||
migrator.rename_column('udp_balancers', 'description', 'desc'),
|
||||
migrator.rename_column('ha_clusters', 'description', 'desc'),
|
||||
migrator.rename_column('cred', 'key_enabled', 'enable'),
|
||||
migrator.rename_column('cred', 'group_id', 'groups'),
|
||||
migrator.rename_column('servers', 'description', 'desc'),
|
||||
migrator.rename_column('servers', 'haproxy_active', 'active'),
|
||||
migrator.rename_column('servers', 'haproxy_metrics', 'metrics'),
|
||||
migrator.rename_column('servers', 'haproxy_alert', 'alert'),
|
||||
migrator.rename_column('servers', 'cred_id', 'cred'),
|
||||
migrator.rename_column('servers', 'enabled', 'enable'),
|
||||
migrator.rename_column('servers', 'group_id', 'groups'),
|
||||
migrator.rename_column('user', 'enabled', 'activeuser'),
|
||||
migrator.rename_column('user', 'group_id', 'groups'),
|
||||
migrator.rename_column('user', 'role_id', 'role'),
|
||||
)
|
||||
except Exception as e:
|
||||
print(f"Error rolling back migration: {str(e)}")
|
||||
raise e
|
|
@ -0,0 +1,34 @@
|
|||
from playhouse.migrate import *
|
||||
from app.modules.db.db_model import connect, mysql_enable
|
||||
from peewee import IntegerField, SQL
|
||||
|
||||
migrator = connect(get_migrator=1)
|
||||
|
||||
def up():
|
||||
"""Apply the migration."""
|
||||
# This migration adds a shared column to the cred table
|
||||
try:
|
||||
if mysql_enable:
|
||||
migrate(
|
||||
migrator.add_column('cred', 'shared', IntegerField(default=0)),
|
||||
)
|
||||
else:
|
||||
migrate(
|
||||
migrator.add_column('cred', 'shared', IntegerField(constraints=[SQL('DEFAULT 0')])),
|
||||
)
|
||||
except Exception as e:
|
||||
if e.args[0] == 'duplicate column name: shared' or str(e) == '(1060, "Duplicate column name \'shared\'")':
|
||||
print('Column already exists')
|
||||
else:
|
||||
raise e
|
||||
|
||||
def down():
|
||||
"""Roll back the migration."""
|
||||
# This migration removes the shared column from the cred table
|
||||
try:
|
||||
migrate(
|
||||
migrator.drop_column('cred', 'shared'),
|
||||
)
|
||||
except Exception as e:
|
||||
print(f"Error rolling back migration: {str(e)}")
|
||||
raise e
|
|
@ -0,0 +1,37 @@
|
|||
from playhouse.migrate import *
|
||||
from app.modules.db.db_model import connect, RoxyTool
|
||||
|
||||
migrator = connect(get_migrator=1)
|
||||
|
||||
def up():
|
||||
"""Apply the migration."""
|
||||
# This migration deletes rows from the RoxyTool table
|
||||
try:
|
||||
RoxyTool.delete().where(RoxyTool.name == 'prometheus').execute()
|
||||
RoxyTool.delete().where(RoxyTool.name == 'grafana-server').execute()
|
||||
except Exception as e:
|
||||
print(f"Error applying migration: {str(e)}")
|
||||
raise e
|
||||
|
||||
def down():
|
||||
"""Roll back the migration."""
|
||||
# This migration adds back the deleted rows to the RoxyTool table
|
||||
try:
|
||||
RoxyTool.insert(
|
||||
name='prometheus',
|
||||
current_version='1.0',
|
||||
new_version='1.0',
|
||||
is_roxy=0,
|
||||
desc='Prometheus monitoring system'
|
||||
).on_conflict_ignore().execute()
|
||||
|
||||
RoxyTool.insert(
|
||||
name='grafana-server',
|
||||
current_version='1.0',
|
||||
new_version='1.0',
|
||||
is_roxy=0,
|
||||
desc='Grafana visualization tool'
|
||||
).on_conflict_ignore().execute()
|
||||
except Exception as e:
|
||||
print(f"Error rolling back migration: {str(e)}")
|
||||
raise e
|
|
@ -0,0 +1,30 @@
|
|||
from playhouse.migrate import *
|
||||
from app.modules.db.db_model import connect
|
||||
|
||||
migrator = connect(get_migrator=1)
|
||||
|
||||
def up():
|
||||
"""Apply the migration."""
|
||||
# This migration renames the server column to server_id in the backups table
|
||||
try:
|
||||
migrate(
|
||||
migrator.rename_column('backups', 'server', 'server_id')
|
||||
)
|
||||
except Exception as e:
|
||||
if e.args[0] == 'no such column: "server"' or str(e) == '(1060, no such column: "server")':
|
||||
print("Column already renamed")
|
||||
elif e.args[0] == "'bool' object has no attribute 'sql'":
|
||||
print("Column already renamed")
|
||||
else:
|
||||
raise e
|
||||
|
||||
def down():
|
||||
"""Roll back the migration."""
|
||||
# This migration renames the server_id column back to server in the backups table
|
||||
try:
|
||||
migrate(
|
||||
migrator.rename_column('backups', 'server_id', 'server')
|
||||
)
|
||||
except Exception as e:
|
||||
print(f"Error rolling back migration: {str(e)}")
|
||||
raise e
|
|
@ -0,0 +1,30 @@
|
|||
from playhouse.migrate import *
|
||||
from app.modules.db.db_model import connect
|
||||
|
||||
migrator = connect(get_migrator=1)
|
||||
|
||||
def up():
|
||||
"""Apply the migration."""
|
||||
# This migration renames the server column to server_id in the s3_backups table
|
||||
try:
|
||||
migrate(
|
||||
migrator.rename_column('s3_backups', 'server', 'server_id')
|
||||
)
|
||||
except Exception as e:
|
||||
if e.args[0] == 'no such column: "server"' or str(e) == '(1060, no such column: "server")':
|
||||
print("Column already renamed")
|
||||
elif e.args[0] == "'bool' object has no attribute 'sql'":
|
||||
print("Column already renamed")
|
||||
else:
|
||||
raise e
|
||||
|
||||
def down():
|
||||
"""Roll back the migration."""
|
||||
# This migration renames the server_id column back to server in the s3_backups table
|
||||
try:
|
||||
migrate(
|
||||
migrator.rename_column('s3_backups', 'server_id', 'server')
|
||||
)
|
||||
except Exception as e:
|
||||
print(f"Error rolling back migration: {str(e)}")
|
||||
raise e
|
|
@ -0,0 +1,30 @@
|
|||
from playhouse.migrate import *
|
||||
from app.modules.db.db_model import connect
|
||||
|
||||
migrator = connect(get_migrator=1)
|
||||
|
||||
def up():
|
||||
"""Apply the migration."""
|
||||
# This migration renames the rhost column to rserver in the backups table
|
||||
try:
|
||||
migrate(
|
||||
migrator.rename_column('backups', 'rhost', 'rserver')
|
||||
)
|
||||
except Exception as e:
|
||||
if e.args[0] == 'no such column: "rhost"' or str(e) == '(1060, no such column: "rhost")':
|
||||
print("Column already renamed")
|
||||
elif e.args[0] == "'bool' object has no attribute 'sql'":
|
||||
print("Column already renamed")
|
||||
else:
|
||||
raise e
|
||||
|
||||
def down():
|
||||
"""Roll back the migration."""
|
||||
# This migration renames the rserver column back to rhost in the backups table
|
||||
try:
|
||||
migrate(
|
||||
migrator.rename_column('backups', 'rserver', 'rhost')
|
||||
)
|
||||
except Exception as e:
|
||||
print(f"Error rolling back migration: {str(e)}")
|
||||
raise e
|
|
@ -0,0 +1,30 @@
|
|||
from playhouse.migrate import *
|
||||
from app.modules.db.db_model import connect
|
||||
|
||||
migrator = connect(get_migrator=1)
|
||||
|
||||
def up():
|
||||
"""Apply the migration."""
|
||||
# This migration renames the period column to time in the git_setting table
|
||||
try:
|
||||
migrate(
|
||||
migrator.rename_column('git_setting', 'period', 'time')
|
||||
)
|
||||
except Exception as e:
|
||||
if e.args[0] == 'no such column: "period"' or str(e) == '(1060, no such column: "period")':
|
||||
print("Column already renamed")
|
||||
elif e.args[0] == "'bool' object has no attribute 'sql'":
|
||||
print("Column already renamed")
|
||||
else:
|
||||
raise e
|
||||
|
||||
def down():
|
||||
"""Roll back the migration."""
|
||||
# This migration renames the time column back to period in the git_setting table
|
||||
try:
|
||||
migrate(
|
||||
migrator.rename_column('git_setting', 'time', 'period')
|
||||
)
|
||||
except Exception as e:
|
||||
print(f"Error rolling back migration: {str(e)}")
|
||||
raise e
|
|
@ -0,0 +1,30 @@
|
|||
from playhouse.migrate import *
|
||||
from app.modules.db.db_model import connect
|
||||
|
||||
migrator = connect(get_migrator=1)
|
||||
|
||||
def up():
|
||||
"""Apply the migration."""
|
||||
# This migration renames the group column to group_id in the settings table
|
||||
try:
|
||||
migrate(
|
||||
migrator.rename_column('settings', 'group', 'group_id'),
|
||||
)
|
||||
except Exception as e:
|
||||
if e.args[0] == 'no such column: "group"' or 'column "group" does not exist' in str(e) or str(e) == '(1060, no such column: "group")':
|
||||
print("Column already renamed")
|
||||
elif e.args[0] == "'bool' object has no attribute 'sql'":
|
||||
print("Column already renamed")
|
||||
else:
|
||||
raise e
|
||||
|
||||
def down():
|
||||
"""Roll back the migration."""
|
||||
# This migration renames the group_id column back to group in the settings table
|
||||
try:
|
||||
migrate(
|
||||
migrator.rename_column('settings', 'group_id', 'group'),
|
||||
)
|
||||
except Exception as e:
|
||||
print(f"Error rolling back migration: {str(e)}")
|
||||
raise e
|
|
@ -0,0 +1,29 @@
|
|||
from playhouse.migrate import *
|
||||
from app.modules.db.db_model import connect, TextField
|
||||
|
||||
migrator = connect(get_migrator=1)
|
||||
|
||||
def up():
|
||||
"""Apply the migration."""
|
||||
# This migration adds a private_key column to the cred table
|
||||
try:
|
||||
migrate(
|
||||
migrator.add_column('cred', 'private_key', TextField(null=True)),
|
||||
)
|
||||
except Exception as e:
|
||||
if (e.args[0] == 'duplicate column name: private_key' or 'column "private_key" of relation "cred" already exists'
|
||||
or str(e) == '(1060, "Duplicate column name \'private_key\'")'):
|
||||
print('Column already exists')
|
||||
else:
|
||||
raise e
|
||||
|
||||
def down():
|
||||
"""Roll back the migration."""
|
||||
# This migration removes the private_key column from the cred table
|
||||
try:
|
||||
migrate(
|
||||
migrator.drop_column('cred', 'private_key'),
|
||||
)
|
||||
except Exception as e:
|
||||
print(f"Error rolling back migration: {str(e)}")
|
||||
raise e
|
|
@ -0,0 +1,35 @@
|
|||
from playhouse.migrate import *
|
||||
from app.modules.db.db_model import connect, mysql_enable
|
||||
from peewee import IntegerField, SQL
|
||||
|
||||
migrator = connect(get_migrator=1)
|
||||
|
||||
def up():
|
||||
"""Apply the migration."""
|
||||
# This migration adds an is_checker column to the udp_balancers table
|
||||
try:
|
||||
if mysql_enable:
|
||||
migrate(
|
||||
migrator.add_column('udp_balancers', 'is_checker', IntegerField(default=0)),
|
||||
)
|
||||
else:
|
||||
migrate(
|
||||
migrator.add_column('udp_balancers', 'is_checker', IntegerField(constraints=[SQL('DEFAULT 0')])),
|
||||
)
|
||||
except Exception as e:
|
||||
if (e.args[0] == 'duplicate column name: is_checker' or 'column "is_checker" of relation "udp_balancers" already exists'
|
||||
or str(e) == '(1060, "Duplicate column name \'is_checker\'")'):
|
||||
print('Column already exists')
|
||||
else:
|
||||
raise e
|
||||
|
||||
def down():
|
||||
"""Roll back the migration."""
|
||||
# This migration removes the is_checker column from the udp_balancers table
|
||||
try:
|
||||
migrate(
|
||||
migrator.drop_column('udp_balancers', 'is_checker'),
|
||||
)
|
||||
except Exception as e:
|
||||
print(f"Error rolling back migration: {str(e)}")
|
||||
raise e
|
|
@ -0,0 +1,22 @@
|
|||
from playhouse.migrate import *
|
||||
from app.modules.db.db_model import connect, Version
|
||||
|
||||
migrator = connect(get_migrator=1)
|
||||
|
||||
def up():
|
||||
"""Apply the migration."""
|
||||
# This migration updates the version in the database to 8.2.0
|
||||
try:
|
||||
Version.update(version='8.2.0').execute()
|
||||
except Exception as e:
|
||||
print(f"Error updating version: {str(e)}")
|
||||
raise e
|
||||
|
||||
def down():
|
||||
"""Roll back the migration."""
|
||||
# This migration sets the version back to 8.1.6
|
||||
try:
|
||||
Version.update(version='8.1.6').execute()
|
||||
except Exception as e:
|
||||
print(f"Error rolling back migration: {str(e)}")
|
||||
raise e
|
|
@ -0,0 +1,60 @@
|
|||
# Database Migrations
|
||||
|
||||
This directory contains database migration files for Roxy-WI. Each migration file represents a specific change to the database schema.
|
||||
|
||||
## Migration System
|
||||
|
||||
The migration system is designed to track which migrations have been applied, apply migrations in the correct order, and support rollbacks. It uses Peewee's migration functionality to make changes to the database schema.
|
||||
|
||||
## Migration Files
|
||||
|
||||
Each migration file is a Python module with two functions:
|
||||
|
||||
- `up()`: Applies the migration
|
||||
- `down()`: Rolls back the migration
|
||||
|
||||
Migration files are named with a timestamp prefix to ensure they are applied in the correct order.
|
||||
|
||||
## Using the Migration System
|
||||
|
||||
The migration system provides a command-line interface for managing migrations. The following commands are available:
|
||||
|
||||
### Initialize the Migrations Table
|
||||
|
||||
```bash
|
||||
python app/migrate.py init
|
||||
```
|
||||
|
||||
This command creates the migrations table in the database if it doesn't exist.
|
||||
|
||||
### Create a New Migration
|
||||
|
||||
```bash
|
||||
python app/migrate.py create <migration_name>
|
||||
```
|
||||
|
||||
This command creates a new migration file with the given name. The file will be created in the migrations directory with a timestamp prefix.
|
||||
|
||||
### Apply Pending Migrations
|
||||
|
||||
```bash
|
||||
python app/migrate.py migrate
|
||||
```
|
||||
|
||||
This command applies all pending migrations in the correct order.
|
||||
|
||||
### Roll Back Migrations
|
||||
|
||||
```bash
|
||||
python app/migrate.py rollback [--steps <number>]
|
||||
```
|
||||
|
||||
This command rolls back the specified number of migrations (default: 1) in reverse order.
|
||||
|
||||
## Automatic Migrations
|
||||
|
||||
The migration system is automatically run when the application starts up. This ensures that the database schema is always up to date.
|
||||
|
||||
## Converting from the Old Update System
|
||||
|
||||
The old update system used multiple update functions in create_db.py to handle database schema changes. These functions have been converted to migration files in this directory. The application now uses the migration system instead of the old update functions.
|
|
@ -0,0 +1 @@
|
|||
# This file makes the migrations directory a Python package
|
Loading…
Reference in New Issue