Skip to content

Commit 999f099

Browse files
committed
db.attach(alias, filepath) method, closes #113
Will also be useful for #236
1 parent 2c1b9f2 commit 999f099

File tree

3 files changed

+45
-0
lines changed

3 files changed

+45
-0
lines changed

docs/python-api.rst

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,27 @@ Connections use ``PRAGMA recursive_triggers=on`` by default. If you don't want t
4545
4646
db = Database(memory=True, recursive_triggers=False)
4747
48+
.. _python_api_attach:
49+
50+
Attaching additional databases
51+
------------------------------
52+
53+
SQLite supports cross-database SQL queries, which can join data from tables in more than one database file. You can attach an additional database using the ``.attach()`` method, providing an alias to use for that database and the path to the SQLite file on disk.
54+
55+
.. code-block:: python
56+
57+
db = Database("first.db")
58+
db.attach("second", "second.db")
59+
# Now you can run queries like this one:
60+
cursor = db.execute("""
61+
select * from table_in_first
62+
union all
63+
select * from second.table_in_second
64+
""")
65+
print(cursor.fetchall())
66+
67+
You can reference tables in the attached database using the alias value you passed to ``db.attach(alias, filepath)`` as a prefix, for example the ``second.table_in_second`` reference in the SQL query above.
68+
4869
.. _python_api_tracing:
4970

5071
Tracing queries

sqlite_utils/db.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,14 @@ def register(fn):
219219
def register_fts4_bm25(self):
220220
self.register_function(rank_bm25, deterministic=True)
221221

222+
def attach(self, alias, filepath):
223+
attach_sql = """
224+
ATTACH DATABASE '{}' AS [{}];
225+
""".format(
226+
str(pathlib.Path(filepath).resolve()), alias
227+
).strip()
228+
self.execute(attach_sql)
229+
222230
def execute(self, sql, parameters=None):
223231
if self._tracer:
224232
self._tracer(sql, parameters)

tests/test_attach.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
from sqlite_utils import Database
2+
3+
4+
def test_attach(tmpdir):
5+
foo_path = str(tmpdir / "foo.db")
6+
bar_path = str(tmpdir / "bar.db")
7+
db = Database(foo_path)
8+
with db.conn:
9+
db["foo"].insert({"id": 1, "text": "foo"})
10+
db2 = Database(bar_path)
11+
with db2.conn:
12+
db2["bar"].insert({"id": 1, "text": "bar"})
13+
db.attach("bar", bar_path)
14+
assert db.execute(
15+
"select * from foo union all select * from bar.bar"
16+
).fetchall() == [(1, "foo"), (1, "bar")]

0 commit comments

Comments
 (0)