Как загрузить существующий файл БД в память в Python sqlite3?

у меня есть sqlite3 db файл, на котором мне нужно сделать некоторые обширные вычисления. Выполнение вычислений из файла происходит мучительно медленно, а так как файл не большой (~10 MB), поэтому не должно быть никаких проблем, чтобы загрузить его в память.

есть ли Питонический способ загрузить существующий файл в память, чтобы ускорить вычисления?

7 ответов


вот фрагмент, который я написал для своего приложения flask:

import sqlite3
from StringIO import StringIO

def init_sqlite_db(app):
    # Read database to tempfile
    con = sqlite3.connect(app.config['SQLITE_DATABASE'])
    tempfile = StringIO()
    for line in con.iterdump():
        tempfile.write('%s\n' % line)
    con.close()
    tempfile.seek(0)

    # Create a database in memory and import from tempfile
    app.sqlite = sqlite3.connect(":memory:")
    app.sqlite.cursor().executescript(tempfile.read())
    app.sqlite.commit()
    app.sqlite.row_factory = sqlite3.Row

sqlite3.Connection.iterdump " [r] eturns итератор для сброса базы данных в текстовом формате SQL. Полезно при сохранении базы данных в памяти для последующего восстановления. Эта функция предоставляет те же возможности, что и .dump команда в оболочке sqlite3."

получите такой итератор и сбросьте дисковую базу данных в базу данных на основе памяти, и вы готовы вычислить. Когда вычисление будет сделано, просто сбросьте другой способ обратно на диск.


сначала вы должны попытаться выяснить, что вызывает медлительность, которую вы наблюдаете. Ты пишешь столам? Являются ли ваши записи достаточно большими сделки чтобы вы не сохраняли ненужные временные результаты на диск? Можете ли вы изменить записи, чтобы перейти к временным таблицам (с pragma temp_store=memory)? Можете ли вы жить с pragma synchronous=off?

Я не думаю, что эта функциональность представлена в модуле Python, но sqlite имеет резервное копирование API это звучит именно так, как вы просите: способ копирования из одной базы данных в другую (любая из которых может быть базой данных в памяти), которая работает почти автоматически без какого-либо видимого пользователем перечисления таблиц. (Возможно APSW выставляет это?)

другой вариант-создать ram-диск (если у вас есть достаточный контроль над средой) и скопировать файл туда.


на это уже был дан ответ, включая примеры кода в в python, как я могу загрузить SQLite db полностью в память перед подключением к нему?

вы не упоминаете операционную систему, но один gotcha из Windows XP является то, что по умолчанию кеш файла 10 МБ, независимо от того, сколько памяти у вас есть. (Это имело смысл в те дни, когда системы поставляются с 64MB и т. д.). Это сообщение имеет несколько ссылки:

http://marc.info/?l=sqlite-users&m=116743785223905&w=2


вот относительно простой способ чтения БД SQLite в память. В зависимости от ваших предпочтений в отношении управления данными вы либо используете Pandas dataframe, либо записываете свою таблицу в базу данных sqlite3 в памяти. Аналогично, после манипулирования вашими данными вы используете тот же df.to_sqlite подход для хранения результатов обратно в таблицу БД.

import sqlite3 as lite
from pandas.io.sql import read_sql
from sqlalchemy import create_engine

engine = create_engine('sqlite://')
c = engine.connect()
conmem = c.connection
con = lite.connect('ait.sqlite', isolation_level=None) #Here is the connection to <ait.sqlite> residing on disk
cur = con.cursor()
sqlx = 'SELECT * FROM Table'
df = read_sql(sqlx, con, coerce_float=True, params=None) 

#Read SQLite table into a panda dataframe
df.to_sql(con=conmem, name='Table', if_exists='replace', flavor='sqlite')

Если мы должны использовать оболочку python, то нет лучшего решения, чем два решения для чтения и записи. но начиная с версии 3.7.17, SQLite имеет возможность доступа к содержимому диска непосредственно с помощью I/O.sqlite mmap

Если вы хотите использовать mmap, вы должны использовать интерфейс C, так как никакая оболочка не предоставляет его.

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


SQLite поддерживает базы данных в памяти.

в python вы бы использовали :объем встроенной памяти: имя базы данных для этого.

возможно, вы могли бы открыть две базы данных (одну из файла, пустую в памяти), перенести все из базы данных файлов в память, а затем использовать базу данных в памяти для дальнейших вычислений.