diff --git a/datasette/utils/internal_db.py b/datasette/utils/internal_db.py index 626dd137..31d4cbd6 100644 --- a/datasette/utils/internal_db.py +++ b/datasette/utils/internal_db.py @@ -17,7 +17,7 @@ async def init_internal_db(db): rootpage INTEGER, sql TEXT, PRIMARY KEY (database_name, table_name), - FOREIGN KEY (database_name) REFERENCES databases(database_name) + FOREIGN KEY (database_name) REFERENCES catalog_databases(database_name) ); CREATE TABLE IF NOT EXISTS catalog_columns ( database_name TEXT, @@ -30,8 +30,8 @@ async def init_internal_db(db): is_pk INTEGER, -- renamed from pk hidden INTEGER, PRIMARY KEY (database_name, table_name, name), - FOREIGN KEY (database_name) REFERENCES databases(database_name), - FOREIGN KEY (database_name, table_name) REFERENCES tables(database_name, table_name) + FOREIGN KEY (database_name) REFERENCES catalog_databases(database_name), + FOREIGN KEY (database_name, table_name) REFERENCES catalog_tables(database_name, table_name) ); CREATE TABLE IF NOT EXISTS catalog_indexes ( database_name TEXT, @@ -42,8 +42,8 @@ async def init_internal_db(db): origin TEXT, partial INTEGER, PRIMARY KEY (database_name, table_name, name), - FOREIGN KEY (database_name) REFERENCES databases(database_name), - FOREIGN KEY (database_name, table_name) REFERENCES tables(database_name, table_name) + FOREIGN KEY (database_name) REFERENCES catalog_databases(database_name), + FOREIGN KEY (database_name, table_name) REFERENCES catalog_tables(database_name, table_name) ); CREATE TABLE IF NOT EXISTS catalog_foreign_keys ( database_name TEXT, @@ -57,8 +57,8 @@ async def init_internal_db(db): on_delete TEXT, match TEXT, PRIMARY KEY (database_name, table_name, id, seq), - FOREIGN KEY (database_name) REFERENCES databases(database_name), - FOREIGN KEY (database_name, table_name) REFERENCES tables(database_name, table_name) + FOREIGN KEY (database_name) REFERENCES catalog_databases(database_name), + FOREIGN KEY (database_name, table_name) REFERENCES catalog_tables(database_name, table_name) ); """ ).strip() diff --git a/docs/internals.rst b/docs/internals.rst index facbc224..9cbb87ef 100644 --- a/docs/internals.rst +++ b/docs/internals.rst @@ -1382,7 +1382,7 @@ The internal database schema is as follows: rootpage INTEGER, sql TEXT, PRIMARY KEY (database_name, table_name), - FOREIGN KEY (database_name) REFERENCES databases(database_name) + FOREIGN KEY (database_name) REFERENCES catalog_databases(database_name) ); CREATE TABLE catalog_columns ( database_name TEXT, @@ -1395,8 +1395,8 @@ The internal database schema is as follows: is_pk INTEGER, -- renamed from pk hidden INTEGER, PRIMARY KEY (database_name, table_name, name), - FOREIGN KEY (database_name) REFERENCES databases(database_name), - FOREIGN KEY (database_name, table_name) REFERENCES tables(database_name, table_name) + FOREIGN KEY (database_name) REFERENCES catalog_databases(database_name), + FOREIGN KEY (database_name, table_name) REFERENCES catalog_tables(database_name, table_name) ); CREATE TABLE catalog_indexes ( database_name TEXT, @@ -1407,8 +1407,8 @@ The internal database schema is as follows: origin TEXT, partial INTEGER, PRIMARY KEY (database_name, table_name, name), - FOREIGN KEY (database_name) REFERENCES databases(database_name), - FOREIGN KEY (database_name, table_name) REFERENCES tables(database_name, table_name) + FOREIGN KEY (database_name) REFERENCES catalog_databases(database_name), + FOREIGN KEY (database_name, table_name) REFERENCES catalog_tables(database_name, table_name) ); CREATE TABLE catalog_foreign_keys ( database_name TEXT, @@ -1422,8 +1422,8 @@ The internal database schema is as follows: on_delete TEXT, match TEXT, PRIMARY KEY (database_name, table_name, id, seq), - FOREIGN KEY (database_name) REFERENCES databases(database_name), - FOREIGN KEY (database_name, table_name) REFERENCES tables(database_name, table_name) + FOREIGN KEY (database_name) REFERENCES catalog_databases(database_name), + FOREIGN KEY (database_name, table_name) REFERENCES catalog_tables(database_name, table_name) ); CREATE TABLE metadata_instance ( key text, diff --git a/tests/test_internal_db.py b/tests/test_internal_db.py index b41cabb4..246d795e 100644 --- a/tests/test_internal_db.py +++ b/tests/test_internal_db.py @@ -1,4 +1,5 @@ import pytest +import sqlite_utils # ensure refresh_schemas() gets called before interacting with internal_db @@ -59,3 +60,25 @@ async def test_internal_foreign_keys(ds_client): "table_name", "from", } + + +@pytest.mark.asyncio +async def test_internal_foreign_key_references(ds_client): + internal_db = await ensure_internal(ds_client) + + def inner(conn): + db = sqlite_utils.Database(conn) + table_names = db.table_names() + for table in db.tables: + for fk in table.foreign_keys: + other_table = fk.other_table + other_column = fk.other_column + message = 'Column "{}.{}" references other column "{}.{}" which does not exist'.format( + table.name, fk.column, other_table, other_column + ) + assert other_table in table_names, message + " (bad table)" + assert other_column in db[other_table].columns_dict, ( + message + " (bad column)" + ) + + await internal_db.execute_fn(inner)