Skip to content

Commit fb7ee5d

Browse files
committed
detect conflicts when schema_directory overlaps with paths in schemas_and_paths config
1 parent 8a30c40 commit fb7ee5d

File tree

3 files changed

+22
-11
lines changed

3 files changed

+22
-11
lines changed

README.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,10 @@ dbt_sqlite:
3333
# connect schemas to paths: at least one of these must be 'main'
3434
schemas_and_paths: 'main=/my_project/data/etl.db;dataset=/my_project/data/dataset_v1.db'
3535

36-
# directory where all *.db files are attached as schema
37-
schema_directory: '/myproject/data/schemas'
36+
# directory where all *.db files are attached as schema, using base filename
37+
# as schema name, and where new schema are created. this can overlap with the dirs of
38+
# files in schemas_and_paths as long as there's no conflicts.
39+
schema_directory: '/myproject/data'
3840

3941
# optional: semi-colon separated list of file paths for SQLite extensions to load.
4042
# digest.so is needed to provide for snapshots to work; see README
@@ -111,9 +113,8 @@ Install the `pytest-dbt-adapter` package and run the test specs in this reposito
111113
```
112114
pip install pytest-dbt-adapter
113115
114-
# these paths need to exist for tests to write data
116+
# this path needs to exist for tests to write database file
115117
mkdir -p /tmp/dbt-sqlite-tests
116-
mkdir -p /tmp/dbt-sqlite-tests/schemas
117118
118119
pytest test/sqlite.dbtspec
119120
```

dbt/adapters/sqlite/connections.py

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,8 @@ def open(cls, connection):
4949
schemas_and_paths = {}
5050
for path_entry in credentials.schemas_and_paths.split(";"):
5151
schema, path = path_entry.split("=", 1)
52-
schemas_and_paths[schema] = path
52+
# store abs path so we can tell if we've attached the file already
53+
schemas_and_paths[schema] = os.path.abspath(path)
5354

5455
try:
5556
if 'main' in schemas_and_paths:
@@ -72,11 +73,20 @@ def open(cls, connection):
7273
attached.append(schema)
7374

7475
for path in glob.glob(os.path.join(credentials.schema_directory, "*.db")):
75-
schema = os.path.basename(path)[:-3]
76-
if path in schema:
77-
raise DatabaseException(
78-
f"cannot attach schema '{schema}': defined in profile but also exists in schema_directory: {path}")
79-
cursor.execute(f"attach '{path}' as '{schema}'")
76+
abs_path = os.path.abspath(path)
77+
78+
# if file was already attached from being defined in schemas_and_paths, ignore it
79+
if not abs_path in schemas_and_paths.values():
80+
schema = os.path.basename(path)[:-3]
81+
82+
# has schema name been used already?
83+
if schema not in attached:
84+
cursor.execute(f"attach '{path}' as '{schema}'")
85+
else:
86+
raise FailedToConnectException(
87+
f"found {path} while scanning schema_directory, but cannot attach it as '{schema}' " +
88+
f"because that schema name is already defined in schemas_and_paths. " +
89+
f"fix your ~/.dbt/profiles.yml file")
8090

8191
# # uncomment these lines to print out SQL: this only happens if statement is successful
8292
# handle.set_trace_callback(print)

test/sqlite.dbtspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ target:
44
database: adapter_test
55
schema: 'main'
66
schemas_and_paths: "main=/tmp/dbt-sqlite-tests/adapter_test.db"
7-
schema_directory: '/tmp/dbt-sqlite-tests/schemas'
7+
schema_directory: '/tmp/dbt-sqlite-tests'
88
extensions: "/home/jeff/git/sqlite-digest/digest.so"
99
threads: 1
1010
sequences:

0 commit comments

Comments
 (0)