diff --git a/datasette/views/table_create_alter.py b/datasette/views/table_create_alter.py index ce43199c..f7775479 100644 --- a/datasette/views/table_create_alter.py +++ b/datasette/views/table_create_alter.py @@ -262,6 +262,9 @@ async def _create_table_ui_context( return None data = { "path": "{}/-/create".format(datasette.urls.database(database_name)), + "foreignKeyTargetsPath": "{}/-/foreign-key-targets".format( + datasette.urls.database(database_name) + ), "databaseName": database_name, "columnTypes": CREATE_TABLE_COLUMN_TYPES, } @@ -836,7 +839,14 @@ class DatabaseForeignKeyTargetsView(BaseView): ): return _error(["Permission denied: need create-table"], 403) - targets = (await db.execute(FOREIGN_KEY_TARGETS_SQL)).dicts() + hidden_tables = await db.execute_fn( + lambda conn: set(sqlite_hidden_table_names(conn)) + ) + targets = [ + target + for target in (await db.execute(FOREIGN_KEY_TARGETS_SQL)).dicts() + if target["fk_table"] not in hidden_tables + ] return Response.json( { "ok": True, diff --git a/docs/json_api.rst b/docs/json_api.rst index dee98ef2..1db46dd2 100644 --- a/docs/json_api.rst +++ b/docs/json_api.rst @@ -2108,7 +2108,7 @@ The ``//-/foreign-key-targets`` endpoint returns the list of tables in GET //-/foreign-key-targets -The response includes only tables with exactly one primary key column. Tables with compound primary keys and tables with no explicit primary key are omitted. +The response includes only tables with exactly one primary key column. Hidden tables, tables with compound primary keys and tables with no explicit primary key are omitted. Each target includes the normalized SQLite type affinity for the primary key column in ``type``. The type is calculated using SQLite's documented affinity rules: ``INT`` maps to ``integer``; ``CHAR``, ``CLOB`` or ``TEXT`` maps to ``text``; ``BLOB`` or no type maps to ``blob``; ``REAL`` and floating-point declared types map to ``real``; everything else maps to ``numeric``. diff --git a/tests/test_api_write.py b/tests/test_api_write.py index 18ffe43d..1d16ad26 100644 --- a/tests/test_api_write.py +++ b/tests/test_api_write.py @@ -1161,6 +1161,10 @@ async def test_foreign_key_targets(ds_write): "create table compound (a integer, b integer, primary key (a, b))" ) await db.execute_write("create table no_pk (name text)") + try: + await db.execute_write("create virtual table search_docs using fts5(body)") + except Exception: + pass response = await ds_write.client.get( "/data/-/foreign-key-targets", @@ -1203,6 +1207,10 @@ async def test_foreign_key_targets(ds_write): }, ], } + assert not any( + target["fk_table"].startswith("search_docs_") + for target in response.json()["targets"] + ) @pytest.mark.asyncio diff --git a/tests/test_table_html.py b/tests/test_table_html.py index 374cc08d..fa01c8ec 100644 --- a/tests/test_table_html.py +++ b/tests/test_table_html.py @@ -994,6 +994,7 @@ async def test_database_create_table_action_button_and_data(): assert database_data_from_soup(soup) == { "createTable": { "path": "/data/-/create", + "foreignKeyTargetsPath": "/data/-/foreign-key-targets", "databaseName": "data", "columnTypes": ["text", "integer", "float", "blob"], },