mirror of
https://github.com/Tautulli/Tautulli.git
synced 2025-08-22 14:13:40 -07:00
Fix database.py
This commit is contained in:
parent
b6f05087c3
commit
c100549b6a
1 changed files with 37 additions and 37 deletions
|
@ -54,7 +54,7 @@ def validate_database(database=None):
|
||||||
return 'Uncaught exception'
|
return 'Uncaught exception'
|
||||||
|
|
||||||
try:
|
try:
|
||||||
connection.execute('SELECT started from session_history')
|
connection.execute("SELECT started from session_history")
|
||||||
connection.close()
|
connection.close()
|
||||||
except (sqlite3.OperationalError, sqlite3.DatabaseError, ValueError) as e:
|
except (sqlite3.OperationalError, sqlite3.DatabaseError, ValueError) as e:
|
||||||
logger.error("Tautulli Database :: Invalid database specified: %s", e)
|
logger.error("Tautulli Database :: Invalid database specified: %s", e)
|
||||||
|
@ -92,11 +92,11 @@ def import_tautulli_db(database=None, method=None, backup=False):
|
||||||
set_is_importing(True)
|
set_is_importing(True)
|
||||||
|
|
||||||
db = MonitorDatabase()
|
db = MonitorDatabase()
|
||||||
db.connection.execute('BEGIN IMMEDIATE')
|
db.connection.execute("BEGIN IMMEDIATE")
|
||||||
db.connection.execute('ATTACH ? AS import_db', [database])
|
db.connection.execute("ATTACH ? AS import_db", [database])
|
||||||
|
|
||||||
try:
|
try:
|
||||||
version_info = db.select_single('SELECT * FROM import_db.version_info WHERE key = "version"')
|
version_info = db.select_single("SELECT * FROM import_db.version_info WHERE key = 'version'")
|
||||||
import_db_version = version_info['value']
|
import_db_version = version_info['value']
|
||||||
except sqlite3.OperationalError:
|
except sqlite3.OperationalError:
|
||||||
import_db_version = 'v2.6.10'
|
import_db_version = 'v2.6.10'
|
||||||
|
@ -105,7 +105,7 @@ def import_tautulli_db(database=None, method=None, backup=False):
|
||||||
import_db_version = helpers.version_to_tuple(import_db_version)
|
import_db_version = helpers.version_to_tuple(import_db_version)
|
||||||
|
|
||||||
# Get the current number of used ids in the session_history table
|
# Get the current number of used ids in the session_history table
|
||||||
session_history_seq = db.select_single('SELECT seq FROM sqlite_sequence WHERE name = "session_history"')
|
session_history_seq = db.select_single("SELECT seq FROM sqlite_sequence WHERE name = 'session_history'")
|
||||||
session_history_rows = session_history_seq.get('seq', 0)
|
session_history_rows = session_history_seq.get('seq', 0)
|
||||||
|
|
||||||
session_history_tables = ('session_history', 'session_history_metadata', 'session_history_media_info')
|
session_history_tables = ('session_history', 'session_history_metadata', 'session_history_media_info')
|
||||||
|
@ -113,11 +113,11 @@ def import_tautulli_db(database=None, method=None, backup=False):
|
||||||
if method == 'merge':
|
if method == 'merge':
|
||||||
logger.info("Tautulli Database :: Creating temporary database tables to re-index grouped session history.")
|
logger.info("Tautulli Database :: Creating temporary database tables to re-index grouped session history.")
|
||||||
for table_name in session_history_tables:
|
for table_name in session_history_tables:
|
||||||
db.action('CREATE TABLE {table}_copy AS SELECT * FROM import_db.{table}'.format(table=table_name))
|
db.action("CREATE TABLE {table}_copy AS SELECT * FROM import_db.{table}".format(table=table_name))
|
||||||
db.action('UPDATE {table}_copy SET id = id + ?'.format(table=table_name),
|
db.action("UPDATE {table}_copy SET id = id + ?".format(table=table_name),
|
||||||
[session_history_rows])
|
[session_history_rows])
|
||||||
if table_name == 'session_history':
|
if table_name == 'session_history':
|
||||||
db.action('UPDATE {table}_copy SET reference_id = reference_id + ?'.format(table=table_name),
|
db.action("UPDATE {table}_copy SET reference_id = reference_id + ?".format(table=table_name),
|
||||||
[session_history_rows])
|
[session_history_rows])
|
||||||
|
|
||||||
# Migrate section_id from session_history_metadata to session_history
|
# Migrate section_id from session_history_metadata to session_history
|
||||||
|
@ -128,28 +128,28 @@ def import_tautulli_db(database=None, method=None, backup=False):
|
||||||
else:
|
else:
|
||||||
from_db_name = 'import_db'
|
from_db_name = 'import_db'
|
||||||
copy = ''
|
copy = ''
|
||||||
db.action('ALTER TABLE {from_db}.session_history{copy} '
|
db.action("ALTER TABLE {from_db}.session_history{copy} "
|
||||||
'ADD COLUMN section_id INTEGER'.format(from_db=from_db_name,
|
"ADD COLUMN section_id INTEGER".format(from_db=from_db_name,
|
||||||
copy=copy))
|
copy=copy))
|
||||||
db.action('UPDATE {from_db}.session_history{copy} SET section_id = ('
|
db.action("UPDATE {from_db}.session_history{copy} SET section_id = ("
|
||||||
'SELECT section_id FROM {from_db}.session_history_metadata{copy} '
|
"SELECT section_id FROM {from_db}.session_history_metadata{copy} "
|
||||||
'WHERE {from_db}.session_history_metadata{copy}.id = '
|
"WHERE {from_db}.session_history_metadata{copy}.id = "
|
||||||
'{from_db}.session_history{copy}.id)'.format(from_db=from_db_name,
|
"{from_db}.session_history{copy}.id)".format(from_db=from_db_name,
|
||||||
copy=copy))
|
copy=copy))
|
||||||
|
|
||||||
# Keep track of all table columns so that duplicates can be removed after importing
|
# Keep track of all table columns so that duplicates can be removed after importing
|
||||||
table_columns = {}
|
table_columns = {}
|
||||||
|
|
||||||
tables = db.select('SELECT name FROM import_db.sqlite_master '
|
tables = db.select("SELECT name FROM import_db.sqlite_master "
|
||||||
'WHERE type = "table" AND name NOT LIKE "sqlite_%"'
|
"WHERE type = 'table' AND name NOT LIKE 'sqlite_%'"
|
||||||
'ORDER BY name')
|
"ORDER BY name")
|
||||||
for table in tables:
|
for table in tables:
|
||||||
table_name = table['name']
|
table_name = table['name']
|
||||||
if table_name == 'sessions' or table_name == 'version_info':
|
if table_name == 'sessions' or table_name == 'version_info':
|
||||||
# Skip temporary sessions table
|
# Skip temporary sessions table
|
||||||
continue
|
continue
|
||||||
|
|
||||||
current_table = db.select('PRAGMA main.table_info({table})'.format(table=table_name))
|
current_table = db.select("PRAGMA main.table_info({table})".format(table=table_name))
|
||||||
if not current_table:
|
if not current_table:
|
||||||
# Skip table does not exits
|
# Skip table does not exits
|
||||||
continue
|
continue
|
||||||
|
@ -158,8 +158,8 @@ def import_tautulli_db(database=None, method=None, backup=False):
|
||||||
|
|
||||||
if method == 'overwrite':
|
if method == 'overwrite':
|
||||||
# Clear the table and reset the autoincrement ids
|
# Clear the table and reset the autoincrement ids
|
||||||
db.action('DELETE FROM {table}'.format(table=table_name))
|
db.action("DELETE FROM {table}".format(table=table_name))
|
||||||
db.action('DELETE FROM sqlite_sequence WHERE name = ?', [table_name])
|
db.action("DELETE FROM sqlite_sequence WHERE name = ?", [table_name])
|
||||||
|
|
||||||
if method == 'merge' and table_name in session_history_tables:
|
if method == 'merge' and table_name in session_history_tables:
|
||||||
from_db_name = 'main'
|
from_db_name = 'main'
|
||||||
|
@ -170,7 +170,7 @@ def import_tautulli_db(database=None, method=None, backup=False):
|
||||||
|
|
||||||
# Get the list of columns to import
|
# Get the list of columns to import
|
||||||
current_columns = [c['name'] for c in current_table]
|
current_columns = [c['name'] for c in current_table]
|
||||||
import_table = db.select('PRAGMA {from_db}.table_info({from_table})'.format(from_db=from_db_name,
|
import_table = db.select("PRAGMA {from_db}.table_info({from_table})".format(from_db=from_db_name,
|
||||||
from_table=from_table_name))
|
from_table=from_table_name))
|
||||||
|
|
||||||
if method == 'merge' and table_name not in session_history_tables:
|
if method == 'merge' and table_name not in session_history_tables:
|
||||||
|
@ -182,29 +182,29 @@ def import_tautulli_db(database=None, method=None, backup=False):
|
||||||
insert_columns = ', '.join(import_columns)
|
insert_columns = ', '.join(import_columns)
|
||||||
|
|
||||||
# Insert the data with ignore instead of replace to be safe
|
# Insert the data with ignore instead of replace to be safe
|
||||||
db.action('INSERT OR IGNORE INTO {table} ({columns}) '
|
db.action("INSERT OR IGNORE INTO {table} ({columns}) "
|
||||||
'SELECT {columns} FROM {from_db}.{from_table}'.format(table=table_name,
|
"SELECT {columns} FROM {from_db}.{from_table}".format(table=table_name,
|
||||||
columns=insert_columns,
|
columns=insert_columns,
|
||||||
from_db=from_db_name,
|
from_db=from_db_name,
|
||||||
from_table=from_table_name))
|
from_table=from_table_name))
|
||||||
|
|
||||||
db.connection.execute('DETACH import_db')
|
db.connection.execute("DETACH import_db")
|
||||||
|
|
||||||
if method == 'merge':
|
if method == 'merge':
|
||||||
for table_name, columns in sorted(table_columns.items()):
|
for table_name, columns in sorted(table_columns.items()):
|
||||||
duplicate_columns = ', '.join([c for c in columns if c not in ('id', 'reference_id')])
|
duplicate_columns = ', '.join([c for c in columns if c not in ('id', 'reference_id')])
|
||||||
logger.info("Tautulli Database :: Removing duplicate rows from database table '%s'.", table_name)
|
logger.info("Tautulli Database :: Removing duplicate rows from database table '%s'.", table_name)
|
||||||
if table_name in session_history_tables[1:]:
|
if table_name in session_history_tables[1:]:
|
||||||
db.action('DELETE FROM {table} WHERE id NOT IN '
|
db.action("DELETE FROM {table} WHERE id NOT IN "
|
||||||
'(SELECT id FROM session_history)'.format(table=table_name))
|
"(SELECT id FROM session_history)".format(table=table_name))
|
||||||
else:
|
else:
|
||||||
db.action('DELETE FROM {table} WHERE id NOT IN '
|
db.action("DELETE FROM {table} WHERE id NOT IN "
|
||||||
'(SELECT MIN(id) FROM {table} GROUP BY {columns})'.format(table=table_name,
|
"(SELECT MIN(id) FROM {table} GROUP BY {columns})".format(table=table_name,
|
||||||
columns=duplicate_columns))
|
columns=duplicate_columns))
|
||||||
|
|
||||||
logger.info("Tautulli Database :: Deleting temporary database tables.")
|
logger.info("Tautulli Database :: Deleting temporary database tables.")
|
||||||
for table_name in session_history_tables:
|
for table_name in session_history_tables:
|
||||||
db.action('DROP TABLE {table}_copy'.format(table=table_name))
|
db.action("DROP TABLE {table}_copy".format(table=table_name))
|
||||||
|
|
||||||
vacuum()
|
vacuum()
|
||||||
|
|
||||||
|
@ -217,7 +217,7 @@ def import_tautulli_db(database=None, method=None, backup=False):
|
||||||
|
|
||||||
def integrity_check():
|
def integrity_check():
|
||||||
monitor_db = MonitorDatabase()
|
monitor_db = MonitorDatabase()
|
||||||
result = monitor_db.select_single('PRAGMA integrity_check')
|
result = monitor_db.select_single("PRAGMA integrity_check")
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
@ -227,7 +227,7 @@ def clear_table(table=None):
|
||||||
|
|
||||||
logger.debug("Tautulli Database :: Clearing database table '%s'." % table)
|
logger.debug("Tautulli Database :: Clearing database table '%s'." % table)
|
||||||
try:
|
try:
|
||||||
monitor_db.action('DELETE FROM %s' % table)
|
monitor_db.action("DELETE FROM %s" % table)
|
||||||
vacuum()
|
vacuum()
|
||||||
return True
|
return True
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
@ -286,7 +286,7 @@ def delete_user_history(user_id=None):
|
||||||
monitor_db = MonitorDatabase()
|
monitor_db = MonitorDatabase()
|
||||||
|
|
||||||
# Get all history associated with the user_id
|
# Get all history associated with the user_id
|
||||||
result = monitor_db.select('SELECT id FROM session_history WHERE user_id = ?',
|
result = monitor_db.select("SELECT id FROM session_history WHERE user_id = ?",
|
||||||
[user_id])
|
[user_id])
|
||||||
row_ids = [row['id'] for row in result]
|
row_ids = [row['id'] for row in result]
|
||||||
|
|
||||||
|
@ -299,7 +299,7 @@ def delete_library_history(section_id=None):
|
||||||
monitor_db = MonitorDatabase()
|
monitor_db = MonitorDatabase()
|
||||||
|
|
||||||
# Get all history associated with the section_id
|
# Get all history associated with the section_id
|
||||||
result = monitor_db.select('SELECT id FROM session_history WHERE section_id = ?',
|
result = monitor_db.select("SELECT id FROM session_history WHERE section_id = ?",
|
||||||
[section_id])
|
[section_id])
|
||||||
row_ids = [row['id'] for row in result]
|
row_ids = [row['id'] for row in result]
|
||||||
|
|
||||||
|
@ -312,7 +312,7 @@ def vacuum():
|
||||||
|
|
||||||
logger.info("Tautulli Database :: Vacuuming database.")
|
logger.info("Tautulli Database :: Vacuuming database.")
|
||||||
try:
|
try:
|
||||||
monitor_db.action('VACUUM')
|
monitor_db.action("VACUUM")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error("Tautulli Database :: Failed to vacuum database: %s" % e)
|
logger.error("Tautulli Database :: Failed to vacuum database: %s" % e)
|
||||||
|
|
||||||
|
@ -322,7 +322,7 @@ def optimize():
|
||||||
|
|
||||||
logger.info("Tautulli Database :: Optimizing database.")
|
logger.info("Tautulli Database :: Optimizing database.")
|
||||||
try:
|
try:
|
||||||
monitor_db.action('PRAGMA optimize')
|
monitor_db.action("PRAGMA optimize")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error("Tautulli Database :: Failed to optimize database: %s" % e)
|
logger.error("Tautulli Database :: Failed to optimize database: %s" % e)
|
||||||
|
|
||||||
|
@ -362,7 +362,7 @@ def make_backup(cleanup=False, scheduler=False):
|
||||||
os.makedirs(backup_folder)
|
os.makedirs(backup_folder)
|
||||||
|
|
||||||
db = MonitorDatabase()
|
db = MonitorDatabase()
|
||||||
db.connection.execute('BEGIN IMMEDIATE')
|
db.connection.execute("BEGIN IMMEDIATE")
|
||||||
shutil.copyfile(db_filename(), backup_file_fp)
|
shutil.copyfile(db_filename(), backup_file_fp)
|
||||||
db.connection.rollback()
|
db.connection.rollback()
|
||||||
|
|
||||||
|
@ -496,6 +496,6 @@ class MonitorDatabase(object):
|
||||||
|
|
||||||
def last_insert_id(self):
|
def last_insert_id(self):
|
||||||
# Get the last insert row id
|
# Get the last insert row id
|
||||||
result = self.select_single(query='SELECT last_insert_rowid() AS last_id')
|
result = self.select_single(query="SELECT last_insert_rowid() AS last_id")
|
||||||
if result:
|
if result:
|
||||||
return result.get('last_id', None)
|
return result.get('last_id', None)
|
Loading…
Add table
Add a link
Reference in a new issue