updated aplications database

This commit is contained in:
ske087
2025-11-22 22:26:23 +02:00
parent 4d6bd537e3
commit c6e254c390
3 changed files with 105 additions and 24 deletions

3
.gitignore vendored
View File

@@ -46,3 +46,6 @@ instance/external_server.conf
*.backup2 *.backup2
/logs /logs
/backups /backups
/config
/data

View File

@@ -17,12 +17,57 @@ logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class DailyMirrorDatabase: class DailyMirrorDatabase:
def __init__(self, host='localhost', user='trasabilitate', password='Initial01!', database='trasabilitate'): def __init__(self, host=None, user=None, password=None, database=None):
self.host = host """Initialize database connection parameters.
self.user = user If not provided, will read from external_server.conf"""
self.password = password # If parameters not provided, read from config file
self.database = database if host is None or user is None or password is None or database is None:
config = self._read_db_config()
self.host = config.get('host', 'db')
self.user = config.get('user', 'trasabilitate')
self.password = config.get('password', 'Initial01!')
self.database = config.get('database', 'trasabilitate')
else:
self.host = host
self.user = user
self.password = password
self.database = database
self.connection = None self.connection = None
def _read_db_config(self):
"""Read database configuration from external_server.conf"""
try:
from flask import current_app
settings_file = os.path.join(current_app.instance_path, 'external_server.conf')
if os.path.exists(settings_file):
settings = {}
with open(settings_file, 'r') as f:
for line in f:
line = line.strip()
# Skip empty lines and comments
if not line or line.startswith('#'):
continue
if '=' in line:
key, value = line.split('=', 1)
settings[key] = value
return {
'host': settings.get('server_domain', 'db'),
'user': settings.get('username', 'trasabilitate'),
'password': settings.get('password', 'Initial01!'),
'database': settings.get('database_name', 'trasabilitate')
}
except Exception as e:
logger.warning(f"Could not read config file, using defaults: {e}")
# Fallback defaults for Docker environment
return {
'host': 'db',
'user': 'trasabilitate',
'password': 'Initial01!',
'database': 'trasabilitate'
}
def connect(self): def connect(self):
"""Establish database connection""" """Establish database connection"""
@@ -33,7 +78,7 @@ class DailyMirrorDatabase:
password=self.password, password=self.password,
database=self.database database=self.database
) )
logger.info("Database connection established") logger.info(f"Database connection established to {self.host}")
return True return True
except Exception as e: except Exception as e:
logger.error(f"Database connection failed: {e}") logger.error(f"Database connection failed: {e}")

View File

@@ -439,16 +439,36 @@ class DatabaseBackupManager:
'message': 'Backup file not found' 'message': 'Backup file not found'
} }
# Use mariadb command to restore (more reliable than Python parsing) # Read the SQL file
# First, read the file and skip problematic first line if needed
with open(file_path, 'r') as f: with open(file_path, 'r') as f:
sql_content = f.read() sql_content = f.read()
# Clean up SQL content to avoid DEFINER issues
import re
# Remove problematic MariaDB sandbox mode comment from first line # Remove problematic MariaDB sandbox mode comment from first line
lines = sql_content.split('\n') lines = sql_content.split('\n')
if lines and lines[0].startswith('/*M!999999'): if lines and lines[0].startswith('/*M!999999'):
sql_content = '\n'.join(lines[1:]) sql_content = '\n'.join(lines[1:])
# Remove DEFINER clauses that cause permission errors
# This regex matches DEFINER=`user`@`host` in various contexts
sql_content = re.sub(
r'/\*!50017 DEFINER=`[^`]+`@`[^`]+`\*/',
'',
sql_content
)
sql_content = re.sub(
r'/\*!50013 DEFINER=`[^`]+`@`[^`]+`\*/',
'',
sql_content
)
sql_content = re.sub(
r'DEFINER=`[^`]+`@`[^`]+`',
'',
sql_content
)
# Build mariadb restore command # Build mariadb restore command
cmd = [ cmd = [
'mariadb', 'mariadb',
@@ -520,6 +540,28 @@ class DatabaseBackupManager:
'message': 'Backup file not found' 'message': 'Backup file not found'
} }
# Read SQL content
with open(file_path, 'r') as f:
sql_content = f.read()
# Clean up SQL content to avoid DEFINER issues (in case data-only backup has them)
import re
sql_content = re.sub(
r'/\*!50017 DEFINER=`[^`]+`@`[^`]+`\*/',
'',
sql_content
)
sql_content = re.sub(
r'/\*!50013 DEFINER=`[^`]+`@`[^`]+`\*/',
'',
sql_content
)
sql_content = re.sub(
r'DEFINER=`[^`]+`@`[^`]+`',
'',
sql_content
)
# First, disable foreign key checks and truncate all tables # First, disable foreign key checks and truncate all tables
# This ensures clean data import without constraint violations # This ensures clean data import without constraint violations
try: try:
@@ -557,10 +599,7 @@ class DatabaseBackupManager:
print(f"Warning during table truncation: {e}") print(f"Warning during table truncation: {e}")
# Continue anyway - the restore might still work # Continue anyway - the restore might still work
# Read and execute SQL file using Python mariadb library # Execute SQL using Python mariadb library
with open(file_path, 'r') as f:
sql_content = f.read()
conn = mariadb.connect( conn = mariadb.connect(
user=self.config['user'], user=self.config['user'],
password=self.config['password'], password=self.config['password'],
@@ -583,8 +622,8 @@ class DatabaseBackupManager:
print(f"Warning executing statement: {stmt_error}") print(f"Warning executing statement: {stmt_error}")
conn.commit() conn.commit()
result_success = True cursor.close()
result_returncode = 0 conn.close()
# Re-enable foreign key checks # Re-enable foreign key checks
try: try:
@@ -603,16 +642,10 @@ class DatabaseBackupManager:
except Exception as e: except Exception as e:
print(f"Warning: Could not re-enable foreign key checks: {e}") print(f"Warning: Could not re-enable foreign key checks: {e}")
if result_success: return {
return { 'success': True,
'success': True, 'message': f'Data restored successfully from {filename} ({executed} statements executed)'
'message': f'Data restored successfully from {filename}' }
}
else:
return {
'success': False,
'message': f'Data restore failed'
}
except Exception as e: except Exception as e:
print(f"Exception during data restore: {e}") print(f"Exception during data restore: {e}")