kopia lustrzana https://github.com/simonw/datasette
Compound primary key support for /db/-/create - closes #1911
Needed for tests in #1864pull/1912/head
rodzic
484bef0d3b
commit
1154048f79
|
@ -701,7 +701,7 @@ async def _table_columns(datasette, database_name):
|
||||||
class TableCreateView(BaseView):
|
class TableCreateView(BaseView):
|
||||||
name = "table-create"
|
name = "table-create"
|
||||||
|
|
||||||
_valid_keys = {"table", "rows", "row", "columns", "pk"}
|
_valid_keys = {"table", "rows", "row", "columns", "pk", "pks"}
|
||||||
_supported_column_types = {
|
_supported_column_types = {
|
||||||
"text",
|
"text",
|
||||||
"integer",
|
"integer",
|
||||||
|
@ -785,18 +785,28 @@ class TableCreateView(BaseView):
|
||||||
return _error(["rows must be a list of objects"])
|
return _error(["rows must be a list of objects"])
|
||||||
|
|
||||||
pk = data.get("pk")
|
pk = data.get("pk")
|
||||||
|
pks = data.get("pks")
|
||||||
|
|
||||||
|
if pk and pks:
|
||||||
|
return _error(["Cannot specify both pk and pks"])
|
||||||
if pk:
|
if pk:
|
||||||
if not isinstance(pk, str):
|
if not isinstance(pk, str):
|
||||||
return _error(["pk must be a string"])
|
return _error(["pk must be a string"])
|
||||||
|
if pks:
|
||||||
|
if not isinstance(pks, list):
|
||||||
|
return _error(["pks must be a list"])
|
||||||
|
for pk in pks:
|
||||||
|
if not isinstance(pk, str):
|
||||||
|
return _error(["pks must be a list of strings"])
|
||||||
|
|
||||||
def create_table(conn):
|
def create_table(conn):
|
||||||
table = sqlite_utils.Database(conn)[table_name]
|
table = sqlite_utils.Database(conn)[table_name]
|
||||||
if rows:
|
if rows:
|
||||||
table.insert_all(rows, pk=pk)
|
table.insert_all(rows, pk=pks or pk)
|
||||||
else:
|
else:
|
||||||
table.create(
|
table.create(
|
||||||
{c["name"]: c["type"] for c in columns},
|
{c["name"]: c["type"] for c in columns},
|
||||||
pk=pk,
|
pk=pks or pk,
|
||||||
)
|
)
|
||||||
return table.schema
|
return table.schema
|
||||||
|
|
||||||
|
|
|
@ -666,6 +666,8 @@ The JSON here describes the table that will be created:
|
||||||
|
|
||||||
If you set this to ``id`` without including an ``id`` column in the list of ``columns``, Datasette will create an integer ID column for you.
|
If you set this to ``id`` without including an ``id`` column in the list of ``columns``, Datasette will create an integer ID column for you.
|
||||||
|
|
||||||
|
* ``pks`` can be used instead of ``pk`` to create a compound primary key. It should be a JSON list of column names to use in that primary key.
|
||||||
|
|
||||||
If the table is successfully created this will return a ``201`` status code and the following response:
|
If the table is successfully created this will return a ``201`` status code and the following response:
|
||||||
|
|
||||||
.. code-block:: json
|
.. code-block:: json
|
||||||
|
|
|
@ -643,6 +643,27 @@ async def test_drop_table(ds_write, scenario):
|
||||||
"row_count": 1,
|
"row_count": 1,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
# Create table with compound primary key
|
||||||
|
(
|
||||||
|
{
|
||||||
|
"table": "five",
|
||||||
|
"row": {"type": "article", "key": 123, "title": "Article 1"},
|
||||||
|
"pks": ["type", "key"],
|
||||||
|
},
|
||||||
|
201,
|
||||||
|
{
|
||||||
|
"ok": True,
|
||||||
|
"database": "data",
|
||||||
|
"table": "five",
|
||||||
|
"table_url": "http://localhost/data/five",
|
||||||
|
"table_api_url": "http://localhost/data/five.json",
|
||||||
|
"schema": (
|
||||||
|
"CREATE TABLE [five] (\n [type] TEXT,\n [key] INTEGER,\n"
|
||||||
|
" [title] TEXT,\n PRIMARY KEY ([type], [key])\n)"
|
||||||
|
),
|
||||||
|
"row_count": 1,
|
||||||
|
},
|
||||||
|
),
|
||||||
# Error: Table is required
|
# Error: Table is required
|
||||||
(
|
(
|
||||||
{
|
{
|
||||||
|
@ -799,6 +820,39 @@ async def test_drop_table(ds_write, scenario):
|
||||||
"errors": ["pk must be a string"],
|
"errors": ["pk must be a string"],
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
# Error: Cannot specify both pk and pks
|
||||||
|
(
|
||||||
|
{
|
||||||
|
"table": "bad",
|
||||||
|
"row": {"id": 1, "name": "Row 1"},
|
||||||
|
"pk": "id",
|
||||||
|
"pks": ["id", "name"],
|
||||||
|
},
|
||||||
|
400,
|
||||||
|
{
|
||||||
|
"ok": False,
|
||||||
|
"errors": ["Cannot specify both pk and pks"],
|
||||||
|
},
|
||||||
|
),
|
||||||
|
# Error: pks must be a list
|
||||||
|
(
|
||||||
|
{
|
||||||
|
"table": "bad",
|
||||||
|
"row": {"id": 1, "name": "Row 1"},
|
||||||
|
"pks": "id",
|
||||||
|
},
|
||||||
|
400,
|
||||||
|
{
|
||||||
|
"ok": False,
|
||||||
|
"errors": ["pks must be a list"],
|
||||||
|
},
|
||||||
|
),
|
||||||
|
# Error: pks must be a list of strings
|
||||||
|
(
|
||||||
|
{"table": "bad", "row": {"id": 1, "name": "Row 1"}, "pks": [1, 2]},
|
||||||
|
400,
|
||||||
|
{"ok": False, "errors": ["pks must be a list of strings"]},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
async def test_create_table(ds_write, input, expected_status, expected_response):
|
async def test_create_table(ds_write, input, expected_status, expected_response):
|
||||||
|
|
Ładowanie…
Reference in New Issue