I want to import a database from disk to memory at application start and on exit export back from memory to disk. I converted this code from C++ to Python. It successfully exports the database from memory to disk:
import sys
from PySide6.QtSql import QSqlDatabase, QSqlQuery
# Create the connection
con_mem = QSqlDatabase.addDatabase("QSQLITE", 'con_mem')
con_mem.setDatabaseName("file::memory:")
con_mem.setConnectOptions('QSQLITE_OPEN_URI;QSQLITE_ENABLE_SHARED_CACHE')
con_disk = QSqlDatabase.addDatabase("QSQLITE", 'con_disk')
con_disk.setDatabaseName("db.sqlite")
# Open the connection
if not con_disk.open() and con_mem.open():
print("Databases open error")
sys.exit(1)
db_mem = QSqlDatabase.database('con_mem')
db_disk = QSqlDatabase.database('con_disk')
def clone_db(scr, des, des_string):
print('Before creating table')
print('scr: ', scr.tables())
print('des: ', des.tables())
# Create a test table at scr
createTableQuery = QSqlQuery(scr)
createTableQuery.exec(
"""
CREATE TABLE contacts (
id INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE NOT NULL,
name VARCHAR(40) NOT NULL,
job VARCHAR(50),
email VARCHAR(40) NOT NULL
)
"""
)
print('After creating table')
print('scr: ', scr.tables())
print('des: ', des.tables())
VacumQuery = QSqlQuery(scr)
VacumQuery.exec(f'VACUUM main INTO "{des_string}"')
print('After vacum')
print('scr: ', scr.tables())
print('des: ', des.tables())
clone_db(db_mem, db_disk, 'db.sqlite')
Output:
Before creating table
scr: []
des: []
After creating table
scr: ['contacts', 'sqlite_sequence']
des: []
After vacum
scr: ['contacts', 'sqlite_sequence']
des: ['contacts', 'sqlite_sequence']
But when I swap scr
and des
this function doesn't work:
clone_db(db_disk, db_mem, 'file::memory:')
Output:
Before creating table
scr: []
des: []
After creating table
scr: ['contacts', 'sqlite_sequence']
des: []
After vacum
scr: ['contacts', 'sqlite_sequence']
des: []
It does not clone the disk database to an in-memory one. What is the problem?
I changed VacumQuery
:
VacumQuery = QSqlQuery(scr)
if not VacumQuery.exec(f'VACUUM main INTO "{des_string}"'):
print(VacumQuery.lastError().text())
Result:
unable to open database: file::memory: Unable to fetch row
Result of different combinations of in-memory database setup and vacuum statement:
# Test 1: No error. Database not imported. A 'file' is created in current directory.
con_mem.setDatabaseName('file:db?mode=memory&cache=shared')
con_mem.setConnectOptions('QSQLITE_OPEN_URI;QSQLITE_ENABLE_SHARED_CACHE')
......
clone_db(db_disk, db_mem, 'file:db?mode=memory&cache=shared')
# Test 2: No error. Database not imported.
con_mem.setDatabaseName(':memory:')
con_mem.setConnectOptions('QSQLITE_OPEN_URI;QSQLITE_ENABLE_SHARED_CACHE')
......
clone_db(db_disk, db_mem, ':memory:')
# Test 3: No error. Database not imported.
con_mem.setDatabaseName(':memory:')
con_mem.setConnectOptions('QSQLITE_ENABLE_SHARED_CACHE')
......
clone_db(db_disk, db_mem, ':memory:')