Как загрузить существующий файл db в память в Python sqlite3? - программирование
Подтвердить что ты не робот

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

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

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

4b9b3361

Ответ 1

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

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

Ответ 2

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

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

Ответ 3

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

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

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

Ответ 4

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

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

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

Ответ 5

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

Вы не упоминаете операционную систему, но одна из них - это то, что она по умолчанию использует кеш-память размером 10 МБ, независимо от того, сколько у вас памяти. (Это имело смысл в дни, когда системы поставлялись с 64 МБ и т.д.). Это сообщение имеет несколько ссылок:

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

Ответ 6

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

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')

Ответ 7

А как насчет sqlite3.Connection.backup(...)? "Этот метод создает резервную копию базы данных SQLite, даже когда к ней обращаются другие клиенты или одновременно по тому же соединению". Доступность: SQLite 3.6.11 или выше. Новое в версии 3.7.

import sqlite3

source = sqlite3.connect('existing_db.db')
dest = sqlite3.connect(':memory:')
source.backup(dest)

Ответ 8

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

В python для этого используется имя базы данных : память:.

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

Ответ 9

Благодаря решению Cenk Alti у меня всегда была ошибка MemoryError с Python 3.7, когда процесс достигал 500 МБ. Только с использованием функции резервного копирования sqlite3 (упомянутой thinwybk) я смог загружать и сохранять большие базы данных SQLite. Также вы можете сделать то же самое с помощью всего 3 строк кода, в обоих направлениях.