Don't link a foreign key that points at a table that does not exist

Closes #1515
This commit is contained in:
Dipak Chaudhari 2026-09-25 00:12:23 +05:30 • committed by GitHub
commit 83cef452ea
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 36 additions and 0 deletions

View file

@ -2317,6 +2317,10 @@ ORDER BY allowed.parent, allowed.child
from datasette.resources import TableResource
other_table = fk["other_table"]
if not await db.table_exists(other_table):
# SQLite accepts a foreign key to a table that does not exist, and
# linking to it would only lead to a 404
return {}
other_column = fk["other_column"]
if other_column is None:
other_pks = await db.primary_keys(other_table)

View file

@ -803,6 +803,38 @@ async def test_table_html_foreign_key_links(ds_client):
]
@pytest.mark.asyncio
async def test_table_html_foreign_key_to_missing_table_is_not_linked():
# https://github.com/simonw/datasette/issues/1515
ds = Datasette([])
db = ds.add_database(
Database(ds, memory_name="test_foreign_key_to_missing_table"), name="data"
)
await db.execute_write_script("""
create table authors (id integer primary key, name text);
create table books (
id integer primary key,
author_id integer references authors(id),
missing_id integer references missing_table(id)
);
insert into authors (id, name) values (1, 'Ada');
insert into books (id, author_id, missing_id) values (1, 1, 7);
""")
response = await ds.client.get("/data/books")
assert response.status_code == 200
table = Soup(response.text, "html.parser").find("table")
cells = {td["class"][0]: str(td) for td in table.select("tbody tr")[0].select("td")}
assert cells["col-author_id"] == (
'<td class="col-author_id type-int">'
'<a href="/data/authors/1">Ada</a> <em>1</em></td>'
)
assert cells["col-missing_id"] == '<td class="col-missing_id type-int">7</td>'
# The JSON labels are left alone as well
data = (await ds.client.get("/data/books.json?_labels=on")).json()
assert data["rows"][0]["missing_id"] == 7
assert data["rows"][0]["author_id"] == {"value": 1, "label": "Ada"}
@pytest.mark.asyncio
async def test_table_html_foreign_key_facets(ds_client):
response = await ds_client.get(