updated aplications database
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -46,3 +46,6 @@ instance/external_server.conf
|
|||||||
*.backup2
|
*.backup2
|
||||||
/logs
|
/logs
|
||||||
/backups
|
/backups
|
||||||
|
/config
|
||||||
|
/data
|
||||||
|
|
||||||
|
|||||||
@@ -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}")
|
||||||
|
|||||||
@@ -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}")
|
||||||
|
|||||||
Reference in New Issue
Block a user