I'd like to merge SQLite databases, and some may be in memory. I create the in-memory databases by specifying the database path as :memory:
. Following this post, using the attach
feature of SQLite seems like both a simple and efficient approach. But how can I specify my in-memory database as the source to attach?
For example, I'd want to do something like:
c1 = sqlite3.connect(":memory:")
c1.execute(...create table, insert a bunch, commit...)
c2 = sqlite3.connect(":memory:")
c2.execute("""
ATTACH ? AS ToMerge;
BEGIN;
INSERT INTO Records SELECT * FROM ToMerge.Records;
COMMIT;
""", (c1.get_attach_id(), ))
but, of course, c1.get_attach_id()
is a method I made up for demonstration purposes, since using the string :memory:
would be ambiguous. How can I specify the existing c1
database?
A plain
:memory:
string connecting to an in-memory database cannot be shared or attached to from other connections.You need to use a
file:
URI filename connection string with a?cache=shared
parameter to be able to share the in-memory database between connections; then you can also attach to it:See the In-Memory Databases documentation.
Note that there can only be one such shared in-memory database; all other in-memory databases must remain private to their connection. Use databases with an actual filesystem storage if you need more complex setups; these are easy enough to clean up afterwards anyway if you create these in a
tempfile.mkdtemp()
temporary directory each.Demo:
Support for in-memory shared-cache connections was added to SQLite version 3.7.13; for Python you can check the version of the underlying library with
sqlite3.sqlite_version
(string) orsqlite3.sqlite_version_info
(tuple with integers):