Skip to content

Commit 1500c19

Browse files
authored
Add more STRICT table support (#604)
* Add more STRICT table support per #344 (comment). * Make `table.transform()` preserve STRICT mode. * Fix mypy failures in PR #604 * Link to SQLITE strict page in a few places
1 parent 88bd372 commit 1500c19

File tree

9 files changed

+182
-5
lines changed

9 files changed

+182
-5
lines changed

docs/cli-reference.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,7 @@ See :ref:`cli_inserting_data`, :ref:`cli_insert_csv_tsv`, :ref:`cli_insert_unstr
289289
--analyze Run ANALYZE at the end of this operation
290290
--load-extension TEXT Path to SQLite extension, with optional :entrypoint
291291
--silent Do not show progress bar
292+
--strict Apply STRICT mode to created table
292293
--ignore Ignore records if pk already exists
293294
--replace Replace records if pk already exists
294295
--truncate Truncate table before inserting records, if table
@@ -345,6 +346,7 @@ See :ref:`cli_upsert`.
345346
--analyze Run ANALYZE at the end of this operation
346347
--load-extension TEXT Path to SQLite extension, with optional :entrypoint
347348
--silent Do not show progress bar
349+
--strict Apply STRICT mode to created table
348350
-h, --help Show this message and exit.
349351

350352

@@ -920,6 +922,7 @@ See :ref:`cli_create_table`.
920922
--replace If table already exists, replace it
921923
--transform If table already exists, try to transform the schema
922924
--load-extension TEXT Path to SQLite extension, with optional :entrypoint
925+
--strict Apply STRICT mode to created table
923926
-h, --help Show this message and exit.
924927

925928

docs/cli.rst

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1972,6 +1972,25 @@ You can specify foreign key relationships between the tables you are creating us
19721972
[author_id] INTEGER REFERENCES [authors]([id])
19731973
)
19741974
1975+
You can create a table in `SQLite STRICT mode <https://www.sqlite.org/stricttables.html>`__ using ``--strict``:
1976+
1977+
.. code-block:: bash
1978+
1979+
sqlite-utils create-table mydb.db mytable id integer name text --strict
1980+
1981+
.. code-block:: bash
1982+
1983+
sqlite-utils tables mydb.db --schema -t
1984+
1985+
.. code-block:: output
1986+
1987+
table schema
1988+
------- ------------------------
1989+
mytable CREATE TABLE [mytable] (
1990+
[id] INTEGER,
1991+
[name] TEXT
1992+
) STRICT
1993+
19751994
If a table with the same name already exists, you will get an error. You can choose to silently ignore this error with ``--ignore``, or you can replace the existing table with a new, empty table using ``--replace``.
19761995

19771996
You can also pass ``--transform`` to transform the existing table to match the new schema. See :ref:`python_api_explicit_create` in the Python library documentation for details of how this option works.
@@ -2018,7 +2037,7 @@ Use ``--ignore`` to ignore the error if the table does not exist.
20182037
Transforming tables
20192038
===================
20202039

2021-
The ``transform`` command allows you to apply complex transformations to a table that cannot be implemented using a regular SQLite ``ALTER TABLE`` command. See :ref:`python_api_transform` for details of how this works.
2040+
The ``transform`` command allows you to apply complex transformations to a table that cannot be implemented using a regular SQLite ``ALTER TABLE`` command. See :ref:`python_api_transform` for details of how this works. The ``transform`` command preserves a table's ``STRICT`` mode.
20222041

20232042
.. code-block:: bash
20242043

docs/python-api.rst

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,12 @@ By default, any :ref:`sqlite-utils plugins <plugins>` that implement the :ref:`p
117117
118118
db = Database(memory=True, execute_plugins=False)
119119
120+
You can pass ``strict=True`` to enable `SQLite STRICT mode <https://www.sqlite.org/stricttables.html>`__ for all tables created using this database object:
121+
122+
.. code-block:: python
123+
124+
db = Database("my_database.db", strict=True)
125+
120126
.. _python_api_attach:
121127

122128
Attaching additional databases
@@ -581,6 +587,15 @@ The ``transform=True`` option will update the table schema if any of the followi
581587

582588
Changes to ``foreign_keys=`` are not currently detected and applied by ``transform=True``.
583589

590+
You can pass ``strict=True`` to create a table in ``STRICT`` mode:
591+
592+
.. code-block:: python
593+
594+
db["cats"].create({
595+
"id": int,
596+
"name": str,
597+
}, strict=True)
598+
584599
.. _python_api_compound_primary_keys:
585600

586601
Compound primary keys
@@ -661,7 +676,7 @@ You can set default values for these methods by accessing the table through the
661676
# Now you can call .insert() like so:
662677
table.insert({"id": 1, "name": "Tracy", "score": 5})
663678
664-
The configuration options that can be specified in this way are ``pk``, ``foreign_keys``, ``column_order``, ``not_null``, ``defaults``, ``batch_size``, ``hash_id``, ``hash_id_columns``, ``alter``, ``ignore``, ``replace``, ``extracts``, ``conversions``, ``columns``. These are all documented below.
679+
The configuration options that can be specified in this way are ``pk``, ``foreign_keys``, ``column_order``, ``not_null``, ``defaults``, ``batch_size``, ``hash_id``, ``hash_id_columns``, ``alter``, ``ignore``, ``replace``, ``extracts``, ``conversions``, ``columns``, ``strict``. These are all documented below.
665680

666681
.. _python_api_defaults_not_null:
667682

@@ -1011,6 +1026,7 @@ The first time this is called the record will be created for ``name="Palm"``. An
10111026
- ``extracts``
10121027
- ``conversions``
10131028
- ``columns``
1029+
- ``strict``
10141030

10151031
.. _python_api_extracts:
10161032

sqlite_utils/cli.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -909,6 +909,12 @@ def inner(fn):
909909
),
910910
load_extension_option,
911911
click.option("--silent", is_flag=True, help="Do not show progress bar"),
912+
click.option(
913+
"--strict",
914+
is_flag=True,
915+
default=False,
916+
help="Apply STRICT mode to created table",
917+
),
912918
)
913919
):
914920
fn = decorator(fn)
@@ -951,6 +957,7 @@ def insert_upsert_implementation(
951957
silent=False,
952958
bulk_sql=None,
953959
functions=None,
960+
strict=False,
954961
):
955962
db = sqlite_utils.Database(path)
956963
_load_extensions(db, load_extension)
@@ -1066,6 +1073,7 @@ def insert_upsert_implementation(
10661073
"replace": replace,
10671074
"truncate": truncate,
10681075
"analyze": analyze,
1076+
"strict": strict,
10691077
}
10701078
if not_null:
10711079
extra_kwargs["not_null"] = set(not_null)
@@ -1186,6 +1194,7 @@ def insert(
11861194
truncate,
11871195
not_null,
11881196
default,
1197+
strict,
11891198
):
11901199
"""
11911200
Insert records from FILE into a table, creating the table if it
@@ -1264,6 +1273,7 @@ def insert(
12641273
silent=silent,
12651274
not_null=not_null,
12661275
default=default,
1276+
strict=strict,
12671277
)
12681278
except UnicodeDecodeError as ex:
12691279
raise click.ClickException(UNICODE_ERROR.format(ex))
@@ -1299,6 +1309,7 @@ def upsert(
12991309
analyze,
13001310
load_extension,
13011311
silent,
1312+
strict,
13021313
):
13031314
"""
13041315
Upsert records based on their primary key. Works like 'insert' but if
@@ -1343,6 +1354,7 @@ def upsert(
13431354
analyze=analyze,
13441355
load_extension=load_extension,
13451356
silent=silent,
1357+
strict=strict,
13461358
)
13471359
except UnicodeDecodeError as ex:
13481360
raise click.ClickException(UNICODE_ERROR.format(ex))
@@ -1511,6 +1523,11 @@ def create_database(path, enable_wal, init_spatialite, load_extension):
15111523
help="If table already exists, try to transform the schema",
15121524
)
15131525
@load_extension_option
1526+
@click.option(
1527+
"--strict",
1528+
is_flag=True,
1529+
help="Apply STRICT mode to created table",
1530+
)
15141531
def create_table(
15151532
path,
15161533
table,
@@ -1523,6 +1540,7 @@ def create_table(
15231540
replace,
15241541
transform,
15251542
load_extension,
1543+
strict,
15261544
):
15271545
"""
15281546
Add a table with the specified columns. Columns should be specified using
@@ -1570,6 +1588,7 @@ def create_table(
15701588
ignore=ignore,
15711589
replace=replace,
15721590
transform=transform,
1591+
strict=strict,
15731592
)
15741593

15751594

0 commit comments

Comments
 (0)