2017-01-17 2 views
0

Контекст:
питона 3.6 скрипт Обновление SQLite БД При несколько раз в день, используя sqlite3 модуль.
База данных ~ 500Mo, каждое обновление добавляет ~ 250Ko.Создание базы данных SQLite заплаты при обновлении

Выпуск:
я передаю каждые обновленные версии базы данных и хотел бы, чтобы уменьшить размер передаваемых данных. Другими словами, я хотел бы передать только обновленный контент (через какой-то патч).
Для этого может быть использована служебная программа sqldiff.exe, тем не менее она требует создать локальную копию базы данных каждый раз, когда я ее обновляю.

Вопрос:
Есть ли способ, с помощью Python (через DB-API 2.0 interface или с использованием других способов в Python), для создания такого рода патч при обновлении базы данных?


Первые мысли:
Не было бы возможно написать патч ( например список действий, которые необходимо сделать, чтобы обновить базу данных) на основе курсора до/во время выполнения совершить?

import sqlite3 

# Open database 
conn = sqlite3.connect('mydb.db') 
cur = conn.cursor() 

# Insert/Update data 
new_data = 3.14 
cur.execute('INSERT INTO mytable VALUES (?)', (new_data,)) 

# KEEP TRACK & Save (commit) the changes 
conn.dump_planned_actions() # ????? 
conn.commit() 
conn.close() 
+1

Расширение [расширение сеанса] (http://www.sqlite.org/sessionintro.html) не включено в Python. –

+0

@CL. знаете ли вы обходные пути? благодаря –

ответ

1

Следующий фрагмент показывает обходной путь, который я нашел.

Он использует метод Sqlite3 set_trace_callback для регистрации всех отправленных операторов SQL и executescript для применения этих операторов.

import sqlite3 

class DBTraceCallbackHandler(object): 
    """Class handling callbacks in order to log sql statements history.""" 
    def __init__(self): 
     self.sql_statements = [] 
    def instance_handler(self, event): 
     self.sql_statements.append(str(event)) 

def database_modification(cursor): 
    # user-defined 
    pass 

def create_patch(db_path): 
    # Openning connection 
    conn = sqlite3.connect(db_path) 
    c = conn.cursor() 
    # Start tracing sql 
    callback_handler = DBTraceCallbackHandler() 
    conn.set_trace_callback(callback_handler.instance_handler) 
    # Modification of database 
    database_modification(c) 
    # End of modification of database 
    conn.commit() 
    c.close() 
    # Generating the patch - selecting sql statements that modify the db 
    idx_rm = [] 
    for idx, sql_statement in enumerate(callback_handler.sql_statements): 
     if not any([sql_statement.startswith(kw) for kw in ['UPDATE', 'INSERT', 'CREATE']]): 
      idx_rm.append(idx) 
    for idx in sorted(idx_rm, reverse=True): 
     del callback_handler.sql_statements[idx] 

    return ';\n'.join(callback_handler.sql_statements) + ';\n' 


def apply_patch(db_path, sql_script): 
    # Openning connection 
    conn = sqlite3.connect(db_path) 
    c = conn.cursor() 
    # Modification of database - apply sql script 
    c.executescript(sql_script) 
    # End of modification of database 
    conn.commit() 
    c.close() 
Смежные вопросы