Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package python-sqlite-utils for
openSUSE:Factory checked in at 2024-01-12 23:45:48
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-sqlite-utils (Old)
and /work/SRC/openSUSE:Factory/.python-sqlite-utils.new.21961 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-sqlite-utils"
Fri Jan 12 23:45:48 2024 rev:6 rq:1138236 version:3.36
Changes:
--------
--- /work/SRC/openSUSE:Factory/python-sqlite-utils/python-sqlite-utils.changes
2023-12-08 22:34:31.401452681 +0100
+++
/work/SRC/openSUSE:Factory/.python-sqlite-utils.new.21961/python-sqlite-utils.changes
2024-01-12 23:46:09.992222430 +0100
@@ -1,0 +2,23 @@
+Fri Jan 12 08:20:52 UTC 2024 - Dirk Müller <[email protected]>
+
+- update to 3.36:
+ * Support for creating tables in SQLite STRICT mode. Thanks,
+ Taj Khattra. (:issue:`344`) CLI commands create-table,
+ insert and upsert all now accept a --strict option. Python
+ methods that can create a table - table.create() and
+ insert/upsert/insert_all/upsert_all all now accept an
+ optional strict=True parameter. The transform command and
+ table.transform() method preserve strict mode when
+ transforming a table.
+ * CLI commands create-table, insert and upsert all now accept a
+ --strict option.
+ * Python methods that can create a table - table.create() and
+ insert/upsert/insert_all/upsert_all all now accept an
+ optional strict=True parameter.
+ * The transform command and table.transform() method preserve
+ strict mode when transforming a table.
+ * The sqlite-utils create-table command now accepts str, int
+ and bytes as aliases for text, integer and blob respectively.
+ (:issue:`606`)
+
+-------------------------------------------------------------------
Old:
----
sqlite-utils-3.35.2.tar.gz
New:
----
sqlite-utils-3.36.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-sqlite-utils.spec ++++++
--- /var/tmp/diff_new_pack.1u4Hvy/_old 2024-01-12 23:46:11.608281579 +0100
+++ /var/tmp/diff_new_pack.1u4Hvy/_new 2024-01-12 23:46:11.624282164 +0100
@@ -1,7 +1,7 @@
#
# spec file for package python-sqlite-utils
#
-# Copyright (c) 2023 SUSE LLC
+# Copyright (c) 2024 SUSE LLC
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -16,11 +16,8 @@
#
-%{?!python_module:%define python_module() python-%{**} python3-%{**}}
-%define skip_python2 1
-%define skip_python36 1
Name: python-sqlite-utils
-Version: 3.35.2
+Version: 3.36
Release: 0
Summary: Python CLI tool and library for manipulating SQLite databases
License: Apache-2.0
++++++ sqlite-utils-3.35.2.tar.gz -> sqlite-utils-3.36.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/sqlite-utils-3.35.2/PKG-INFO
new/sqlite-utils-3.36/PKG-INFO
--- old/sqlite-utils-3.35.2/PKG-INFO 2023-11-04 02:17:11.781244500 +0100
+++ new/sqlite-utils-3.36/PKG-INFO 2023-12-08 06:36:17.164974500 +0100
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: sqlite-utils
-Version: 3.35.2
+Version: 3.36
Summary: CLI tool and Python library for manipulating SQLite databases
Home-page: https://github.com/simonw/sqlite-utils
Author: Simon Willison
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/sqlite-utils-3.35.2/docs/changelog.rst
new/sqlite-utils-3.36/docs/changelog.rst
--- old/sqlite-utils-3.35.2/docs/changelog.rst 2023-11-04 02:17:02.000000000
+0100
+++ new/sqlite-utils-3.36/docs/changelog.rst 2023-12-08 06:36:09.000000000
+0100
@@ -4,6 +4,17 @@
Changelog
===========
+.. _v3_36:
+
+3.36 (2023-12-07)
+-----------------
+
+- Support for creating tables in `SQLite STRICT mode
<https://www.sqlite.org/stricttables.html>`__. Thanks, `Taj Khattra
<https://github.com/tkhattra>`__. (:issue:`344`)
+ - CLI commands ``create-table``, ``insert`` and ``upsert`` all now accept
a ``--strict`` option.
+ - Python methods that can create a table - ``table.create()`` and
``insert/upsert/insert_all/upsert_all`` all now accept an optional
``strict=True`` parameter.
+ - The ``transform`` command and ``table.transform()`` method preserve
strict mode when transforming a table.
+- The ``sqlite-utils create-table`` command now accepts ``str``, ``int`` and
``bytes`` as aliases for ``text``, ``integer`` and ``blob`` respectively.
(:issue:`606`)
+
.. _v3_35_2:
3.35.2 (2023-11-03)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/sqlite-utils-3.35.2/docs/cli-reference.rst
new/sqlite-utils-3.36/docs/cli-reference.rst
--- old/sqlite-utils-3.35.2/docs/cli-reference.rst 2023-11-04
02:17:02.000000000 +0100
+++ new/sqlite-utils-3.36/docs/cli-reference.rst 2023-12-08
06:36:09.000000000 +0100
@@ -289,6 +289,7 @@
--analyze Run ANALYZE at the end of this operation
--load-extension TEXT Path to SQLite extension, with optional
:entrypoint
--silent Do not show progress bar
+ --strict Apply STRICT mode to created table
--ignore Ignore records if pk already exists
--replace Replace records if pk already exists
--truncate Truncate table before inserting records, if
table
@@ -345,6 +346,7 @@
--analyze Run ANALYZE at the end of this operation
--load-extension TEXT Path to SQLite extension, with optional
:entrypoint
--silent Do not show progress bar
+ --strict Apply STRICT mode to created table
-h, --help Show this message and exit.
@@ -920,6 +922,7 @@
--replace If table already exists, replace it
--transform If table already exists, try to transform the
schema
--load-extension TEXT Path to SQLite extension, with optional
:entrypoint
+ --strict Apply STRICT mode to created table
-h, --help Show this message and exit.
@@ -1157,7 +1160,7 @@
::
Usage: sqlite-utils add-column [OPTIONS] PATH TABLE COL_NAME
- [[integer|float|blob|text|INTEGER|FLOAT|BLOB|TEXT]]
+ [[integer|int|float|text|str|blob|bytes]]
Add a column to the specified table
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/sqlite-utils-3.35.2/docs/cli.rst
new/sqlite-utils-3.36/docs/cli.rst
--- old/sqlite-utils-3.35.2/docs/cli.rst 2023-11-04 02:17:02.000000000
+0100
+++ new/sqlite-utils-3.36/docs/cli.rst 2023-12-08 06:36:09.000000000 +0100
@@ -1972,6 +1972,25 @@
[author_id] INTEGER REFERENCES [authors]([id])
)
+You can create a table in `SQLite STRICT mode
<https://www.sqlite.org/stricttables.html>`__ using ``--strict``:
+
+.. code-block:: bash
+
+ sqlite-utils create-table mydb.db mytable id integer name text --strict
+
+.. code-block:: bash
+
+ sqlite-utils tables mydb.db --schema -t
+
+.. code-block:: output
+
+ table schema
+ ------- ------------------------
+ mytable CREATE TABLE [mytable] (
+ [id] INTEGER,
+ [name] TEXT
+ ) STRICT
+
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``.
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 @@
Transforming tables
===================
-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 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.
.. code-block:: bash
@@ -2310,7 +2329,14 @@
sqlite-utils add-column mydb.db mytable nameofcolumn text
-The last argument here is the type of the column to be created. You can use
one of ``text``, ``integer``, ``float`` or ``blob``. If you leave it off,
``text`` will be used.
+The last argument here is the type of the column to be created. This can be
one of:
+
+- ``text`` or ``str``
+- ``integer`` or ``int``
+- ``float``
+- ``blob`` or ``bytes``
+
+This argument is optional and defaults to ``text``.
You can add a column that is a foreign key reference to another table using
the ``--fk`` option:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/sqlite-utils-3.35.2/docs/plugins.rst
new/sqlite-utils-3.36/docs/plugins.rst
--- old/sqlite-utils-3.35.2/docs/plugins.rst 2023-11-04 02:17:02.000000000
+0100
+++ new/sqlite-utils-3.36/docs/plugins.rst 2023-12-08 06:36:09.000000000
+0100
@@ -49,7 +49,7 @@
[project.entry-points.sqlite_utils]
hello_world = "sqlite_utils_hello_world"
-The ```[project.entry-points.sqlite_utils]`` section tells ``sqlite-tils``
which module to load when executing the plugin.
+The ``[project.entry-points.sqlite_utils]`` section tells ``sqlite-utils``
which module to load when executing the plugin.
Then create ``sqlite_utils_hello_world.py`` with the following content:
@@ -75,7 +75,7 @@
.. code-block:: bash
- sqlite-utils install -e `/dev/sqlite-utils-hello-world
+ sqlite-utils install -e /dev/sqlite-utils-hello-world
Now, running this should execute your new command:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/sqlite-utils-3.35.2/docs/python-api.rst
new/sqlite-utils-3.36/docs/python-api.rst
--- old/sqlite-utils-3.35.2/docs/python-api.rst 2023-11-04 02:17:02.000000000
+0100
+++ new/sqlite-utils-3.36/docs/python-api.rst 2023-12-08 06:36:09.000000000
+0100
@@ -117,6 +117,12 @@
db = Database(memory=True, execute_plugins=False)
+You can pass ``strict=True`` to enable `SQLite STRICT mode
<https://www.sqlite.org/stricttables.html>`__ for all tables created using this
database object:
+
+.. code-block:: python
+
+ db = Database("my_database.db", strict=True)
+
.. _python_api_attach:
Attaching additional databases
@@ -581,6 +587,15 @@
Changes to ``foreign_keys=`` are not currently detected and applied by
``transform=True``.
+You can pass ``strict=True`` to create a table in ``STRICT`` mode:
+
+.. code-block:: python
+
+ db["cats"].create({
+ "id": int,
+ "name": str,
+ }, strict=True)
+
.. _python_api_compound_primary_keys:
Compound primary keys
@@ -661,7 +676,7 @@
# Now you can call .insert() like so:
table.insert({"id": 1, "name": "Tracy", "score": 5})
-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.
+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.
.. _python_api_defaults_not_null:
@@ -1011,6 +1026,7 @@
- ``extracts``
- ``conversions``
- ``columns``
+- ``strict``
.. _python_api_extracts:
@@ -2161,6 +2177,18 @@
>>> db["authors"].has_counts_triggers
True
+.. _python_api_introspection_supports_strict
+
+db.supports_strict
+------------------
+
+This property on the database object returns ``True`` if the available SQLite
version supports `STRICT mode <https://www.sqlite.org/stricttables.html>`__,
which was added in SQLite 3.37.0 (on 2021-11-27).
+
+::
+
+ >>> db.supports_strict
+ True
+
.. _python_api_fts:
Full-text search
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/sqlite-utils-3.35.2/setup.py
new/sqlite-utils-3.36/setup.py
--- old/sqlite-utils-3.35.2/setup.py 2023-11-04 02:17:02.000000000 +0100
+++ new/sqlite-utils-3.36/setup.py 2023-12-08 06:36:09.000000000 +0100
@@ -2,7 +2,7 @@
import io
import os
-VERSION = "3.35.2"
+VERSION = "3.36"
def get_long_description():
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/sqlite-utils-3.35.2/sqlite_utils/cli.py
new/sqlite-utils-3.36/sqlite_utils/cli.py
--- old/sqlite-utils-3.35.2/sqlite_utils/cli.py 2023-11-04 02:17:02.000000000
+0100
+++ new/sqlite-utils-3.36/sqlite_utils/cli.py 2023-12-08 06:36:09.000000000
+0100
@@ -60,6 +60,14 @@
maximize_csv_field_size_limit()
+class CaseInsensitiveChoice(click.Choice):
+ def __init__(self, choices):
+ super().__init__([choice.lower() for choice in choices])
+
+ def convert(self, value, param, ctx):
+ return super().convert(value.lower(), param, ctx)
+
+
def output_options(fn):
for decorator in reversed(
(
@@ -412,7 +420,8 @@
@click.argument(
"col_type",
type=click.Choice(
- ["integer", "float", "blob", "text", "INTEGER", "FLOAT", "BLOB",
"TEXT"]
+ ["integer", "int", "float", "text", "str", "blob", "bytes"],
+ case_sensitive=False,
),
required=False,
)
@@ -900,6 +909,12 @@
),
load_extension_option,
click.option("--silent", is_flag=True, help="Do not show
progress bar"),
+ click.option(
+ "--strict",
+ is_flag=True,
+ default=False,
+ help="Apply STRICT mode to created table",
+ ),
)
):
fn = decorator(fn)
@@ -942,6 +957,7 @@
silent=False,
bulk_sql=None,
functions=None,
+ strict=False,
):
db = sqlite_utils.Database(path)
_load_extensions(db, load_extension)
@@ -1057,6 +1073,7 @@
"replace": replace,
"truncate": truncate,
"analyze": analyze,
+ "strict": strict,
}
if not_null:
extra_kwargs["not_null"] = set(not_null)
@@ -1177,6 +1194,7 @@
truncate,
not_null,
default,
+ strict,
):
"""
Insert records from FILE into a table, creating the table if it
@@ -1255,6 +1273,7 @@
silent=silent,
not_null=not_null,
default=default,
+ strict=strict,
)
except UnicodeDecodeError as ex:
raise click.ClickException(UNICODE_ERROR.format(ex))
@@ -1290,6 +1309,7 @@
analyze,
load_extension,
silent,
+ strict,
):
"""
Upsert records based on their primary key. Works like 'insert' but if
@@ -1334,6 +1354,7 @@
analyze=analyze,
load_extension=load_extension,
silent=silent,
+ strict=strict,
)
except UnicodeDecodeError as ex:
raise click.ClickException(UNICODE_ERROR.format(ex))
@@ -1502,6 +1523,11 @@
help="If table already exists, try to transform the schema",
)
@load_extension_option
[email protected](
+ "--strict",
+ is_flag=True,
+ help="Apply STRICT mode to created table",
+)
def create_table(
path,
table,
@@ -1514,6 +1540,7 @@
replace,
transform,
load_extension,
+ strict,
):
"""
Add a table with the specified columns. Columns should be specified using
@@ -1561,6 +1588,7 @@
ignore=ignore,
replace=replace,
transform=transform,
+ strict=strict,
)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/sqlite-utils-3.35.2/sqlite_utils/db.py
new/sqlite-utils-3.36/sqlite_utils/db.py
--- old/sqlite-utils-3.35.2/sqlite_utils/db.py 2023-11-04 02:17:02.000000000
+0100
+++ new/sqlite-utils-3.36/sqlite_utils/db.py 2023-12-08 06:36:09.000000000
+0100
@@ -197,9 +197,12 @@
"FLOAT": "FLOAT",
"BLOB": "BLOB",
"text": "TEXT",
+ "str": "TEXT",
"integer": "INTEGER",
+ "int": "INTEGER",
"float": "FLOAT",
"blob": "BLOB",
+ "bytes": "BLOB",
}
# If numpy is available, add more types
if np:
@@ -300,6 +303,7 @@
``sql, parameters`` every time a SQL query is executed
:param use_counts_table: set to ``True`` to use a cached counts table, if
available. See
:ref:`python_api_cached_table_counts`
+ :param strict: Apply STRICT mode to all created tables (unless overridden)
"""
_counts_table_name = "_counts"
@@ -315,6 +319,7 @@
tracer: Optional[Callable] = None,
use_counts_table: bool = False,
execute_plugins: bool = True,
+ strict: bool = False,
):
assert (filename_or_conn is not None and (not memory and not
memory_name)) or (
filename_or_conn is None and (memory or memory_name)
@@ -348,6 +353,7 @@
self.use_counts_table = use_counts_table
if execute_plugins:
pm.hook.prepare_connection(conn=self.conn)
+ self.strict = strict
def close(self):
"Close the SQLite connection, and the underlying database file"
@@ -534,8 +540,11 @@
:param table_name: Name of the table
"""
- klass = View if table_name in self.view_names() else Table
- return klass(self, table_name, **kwargs)
+ if table_name in self.view_names():
+ return View(self, table_name, **kwargs)
+ else:
+ kwargs.setdefault("strict", self.strict)
+ return Table(self, table_name, **kwargs)
def quote(self, value: str) -> str:
"""
@@ -821,6 +830,7 @@
hash_id_columns: Optional[Iterable[str]] = None,
extracts: Optional[Union[Dict[str, str], List[str]]] = None,
if_not_exists: bool = False,
+ strict: bool = False,
) -> str:
"""
Returns the SQL ``CREATE TABLE`` statement for creating the specified
table.
@@ -836,6 +846,7 @@
:param hash_id_columns: List of columns to be used when calculating
the hash ID for a row
:param extracts: List or dictionary of columns to be extracted during
inserts, see :ref:`python_api_extracts`
:param if_not_exists: Use ``CREATE TABLE IF NOT EXISTS``
+ :param strict: Apply STRICT mode to table
"""
if hash_id_columns and (hash_id is None):
hash_id = "id"
@@ -932,12 +943,13 @@
columns_sql = ",\n".join(column_defs)
sql = """CREATE TABLE {if_not_exists}[{table}] (
{columns_sql}{extra_pk}
-);
+){strict};
""".format(
if_not_exists="IF NOT EXISTS " if if_not_exists else "",
table=name,
columns_sql=columns_sql,
extra_pk=extra_pk,
+ strict=" STRICT" if strict and self.supports_strict else "",
)
return sql
@@ -957,6 +969,7 @@
replace: bool = False,
ignore: bool = False,
transform: bool = False,
+ strict: bool = False,
) -> "Table":
"""
Create a table with the specified name and the specified
``{column_name: type}`` columns.
@@ -977,6 +990,7 @@
:param replace: Drop and replace table if it already exists
:param ignore: Silently do nothing if table already exists
:param transform: If table already exists transform it to fit the
specified schema
+ :param strict: Apply STRICT mode to table
"""
# Transform table to match the new definition if table already exists:
if self[name].exists():
@@ -1048,6 +1062,7 @@
hash_id_columns=hash_id_columns,
extracts=extracts,
if_not_exists=if_not_exists,
+ strict=strict,
)
self.execute(sql)
created_table = self.table(
@@ -1416,6 +1431,7 @@
:param extracts: Dictionary or list of column names to extract into a
separate table on inserts
:param conversions: Dictionary of column names and conversion functions
:param columns: Dictionary of column names to column types
+ :param strict: If True, apply STRICT mode to table
"""
#: The ``rowid`` of the last inserted, updated or selected row.
@@ -1441,6 +1457,7 @@
extracts: Optional[Union[Dict[str, str], List[str]]] = None,
conversions: Optional[dict] = None,
columns: Optional[Dict[str, Any]] = None,
+ strict: bool = False,
):
super().__init__(db, name)
self._defaults = dict(
@@ -1458,6 +1475,7 @@
extracts=extracts,
conversions=conversions or {},
columns=columns,
+ strict=strict,
)
def __repr__(self) -> str:
@@ -1639,6 +1657,7 @@
replace: bool = False,
ignore: bool = False,
transform: bool = False,
+ strict: bool = False,
) -> "Table":
"""
Create a table with the specified columns.
@@ -1658,6 +1677,7 @@
:param replace: Drop and replace table if it already exists
:param ignore: Silently do nothing if table already exists
:param transform: If table already exists transform it to fit the
specified schema
+ :param strict: Apply STRICT mode to table
"""
columns = {name: value for (name, value) in columns.items()}
with self.db.conn:
@@ -1676,6 +1696,7 @@
replace=replace,
ignore=ignore,
transform=transform,
+ strict=strict,
)
return self
@@ -1909,6 +1930,7 @@
defaults=create_table_defaults,
foreign_keys=create_table_foreign_keys,
column_order=column_order,
+ strict=self.strict,
).strip()
)
@@ -3111,6 +3133,7 @@
extracts: Optional[Union[Dict[str, str], List[str], Default]] =
DEFAULT,
conversions: Optional[Union[Dict[str, str], Default]] = DEFAULT,
columns: Optional[Union[Dict[str, Any], Default]] = DEFAULT,
+ strict: Optional[Union[bool, Default]] = DEFAULT,
) -> "Table":
"""
Insert a single record into the table. The table will be created with
a schema that matches
@@ -3143,6 +3166,7 @@
is being inserted, for example ``{"name": "upper(?)"}``. See
:ref:`python_api_conversions`.
:param columns: Dictionary over-riding the detected types used for the
columns, for example
``{"age": int, "weight": float}``.
+ :param strict: Boolean, apply STRICT mode if creating the table.
"""
return self.insert_all(
[record],
@@ -3159,6 +3183,7 @@
extracts=extracts,
conversions=conversions,
columns=columns,
+ strict=strict,
)
def insert_all(
@@ -3181,6 +3206,7 @@
columns=DEFAULT,
upsert=False,
analyze=False,
+ strict=DEFAULT,
) -> "Table":
"""
Like ``.insert()`` but takes a list of records and ensures that the
table
@@ -3202,6 +3228,7 @@
extracts = self.value_or_default("extracts", extracts)
conversions = self.value_or_default("conversions", conversions) or {}
columns = self.value_or_default("columns", columns)
+ strict = self.value_or_default("strict", strict)
if hash_id_columns and hash_id is None:
hash_id = "id"
@@ -3257,6 +3284,7 @@
hash_id=hash_id,
hash_id_columns=hash_id_columns,
extracts=extracts,
+ strict=strict,
)
all_columns_set = set()
for record in chunk:
@@ -3307,6 +3335,7 @@
extracts=DEFAULT,
conversions=DEFAULT,
columns=DEFAULT,
+ strict=DEFAULT,
) -> "Table":
"""
Like ``.insert()`` but performs an ``UPSERT``, where records are
inserted if they do
@@ -3327,6 +3356,7 @@
extracts=extracts,
conversions=conversions,
columns=columns,
+ strict=strict,
)
def upsert_all(
@@ -3345,6 +3375,7 @@
conversions=DEFAULT,
columns=DEFAULT,
analyze=False,
+ strict=DEFAULT,
) -> "Table":
"""
Like ``.upsert()`` but can be applied to a list of records.
@@ -3365,6 +3396,7 @@
columns=columns,
upsert=True,
analyze=analyze,
+ strict=strict,
)
def add_missing_columns(self, records: Iterable[Dict[str, Any]]) ->
"Table":
@@ -3387,6 +3419,7 @@
extracts: Optional[Union[Dict[str, str], List[str]]] = None,
conversions: Optional[Dict[str, str]] = None,
columns: Optional[Dict[str, Any]] = None,
+ strict: Optional[bool] = False,
):
"""
Create or populate a lookup table with the specified values.
@@ -3409,6 +3442,7 @@
:param lookup_values: Dictionary specifying column names and values to
use for the lookup
:param extra_values: Additional column values to be used only if
creating a new record
+ :param strict: Boolean, apply STRICT mode if creating the table.
"""
assert isinstance(lookup_values, dict)
if extra_values is not None:
@@ -3440,6 +3474,7 @@
extracts=extracts,
conversions=conversions,
columns=columns,
+ strict=strict,
).last_pk
else:
pk = self.insert(
@@ -3452,6 +3487,7 @@
extracts=extracts,
conversions=conversions,
columns=columns,
+ strict=strict,
).last_pk
self.create_index(lookup_values.keys(), unique=True)
return pk
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/sqlite-utils-3.35.2/sqlite_utils.egg-info/PKG-INFO
new/sqlite-utils-3.36/sqlite_utils.egg-info/PKG-INFO
--- old/sqlite-utils-3.35.2/sqlite_utils.egg-info/PKG-INFO 2023-11-04
02:17:11.000000000 +0100
+++ new/sqlite-utils-3.36/sqlite_utils.egg-info/PKG-INFO 2023-12-08
06:36:17.000000000 +0100
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: sqlite-utils
-Version: 3.35.2
+Version: 3.36
Summary: CLI tool and Python library for manipulating SQLite databases
Home-page: https://github.com/simonw/sqlite-utils
Author: Simon Willison
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/sqlite-utils-3.35.2/tests/test_cli.py
new/sqlite-utils-3.36/tests/test_cli.py
--- old/sqlite-utils-3.35.2/tests/test_cli.py 2023-11-04 02:17:02.000000000
+0100
+++ new/sqlite-utils-3.36/tests/test_cli.py 2023-12-08 06:36:09.000000000
+0100
@@ -272,13 +272,23 @@
"col_name,col_type,expected_schema",
(
("text", "TEXT", "CREATE TABLE [dogs] (\n [name] TEXT\n, [text]
TEXT)"),
+ ("text", "str", "CREATE TABLE [dogs] (\n [name] TEXT\n, [text]
TEXT)"),
+ ("text", "STR", "CREATE TABLE [dogs] (\n [name] TEXT\n, [text]
TEXT)"),
(
"integer",
"INTEGER",
"CREATE TABLE [dogs] (\n [name] TEXT\n, [integer] INTEGER)",
),
+ (
+ "integer",
+ "int",
+ "CREATE TABLE [dogs] (\n [name] TEXT\n, [integer] INTEGER)",
+ ),
("float", "FLOAT", "CREATE TABLE [dogs] (\n [name] TEXT\n, [float]
FLOAT)"),
("blob", "blob", "CREATE TABLE [dogs] (\n [name] TEXT\n, [blob]
BLOB)"),
+ ("blob", "BLOB", "CREATE TABLE [dogs] (\n [name] TEXT\n, [blob]
BLOB)"),
+ ("blob", "bytes", "CREATE TABLE [dogs] (\n [name] TEXT\n, [blob]
BLOB)"),
+ ("blob", "BYTES", "CREATE TABLE [dogs] (\n [name] TEXT\n, [blob]
BLOB)"),
("default", None, "CREATE TABLE [dogs] (\n [name] TEXT\n, [default]
TEXT)"),
),
)
@@ -2391,3 +2401,32 @@
catch_exceptions=False,
)
assert result.exit_code == 1
+
+
[email protected]("strict", (False, True))
+def test_create_table_strict(strict):
+ runner = CliRunner()
+ with runner.isolated_filesystem():
+ db = Database("test.db")
+ result = runner.invoke(
+ cli.cli,
+ ["create-table", "test.db", "items", "id", "integer"]
+ + (["--strict"] if strict else []),
+ )
+ assert result.exit_code == 0
+ assert db["items"].strict == strict or not db.supports_strict
+
+
[email protected]("method", ("insert", "upsert"))
[email protected]("strict", (False, True))
+def test_insert_upsert_strict(tmpdir, method, strict):
+ db_path = str(tmpdir / "test.db")
+ result = CliRunner().invoke(
+ cli.cli,
+ [method, db_path, "items", "-", "--csv", "--pk", "id"]
+ + (["--strict"] if strict else []),
+ input="id\n1",
+ )
+ assert result.exit_code == 0
+ db = Database(db_path)
+ assert db["items"].strict == strict or not db.supports_strict
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/sqlite-utils-3.35.2/tests/test_create.py
new/sqlite-utils-3.36/tests/test_create.py
--- old/sqlite-utils-3.35.2/tests/test_create.py 2023-11-04
02:17:02.000000000 +0100
+++ new/sqlite-utils-3.36/tests/test_create.py 2023-12-08 06:36:09.000000000
+0100
@@ -1316,3 +1316,46 @@
# Should error if table does not exist:
with pytest.raises(sqlite3.OperationalError):
fresh_db.rename_table("does_not_exist", "renamed")
+
+
[email protected]("strict", (False, True))
+def test_database_strict(strict):
+ db = Database(memory=True, strict=strict)
+ table = db.table("t", columns={"id": int})
+ table.insert({"id": 1})
+ assert table.strict == strict or not db.supports_strict
+
+
[email protected]("strict", (False, True))
+def test_database_strict_override(strict):
+ db = Database(memory=True, strict=strict)
+ table = db.table("t", columns={"id": int}, strict=not strict)
+ table.insert({"id": 1})
+ assert table.strict != strict or not db.supports_strict
+
+
[email protected](
+ "method_name", ("insert", "upsert", "insert_all", "upsert_all")
+)
[email protected]("strict", (False, True))
+def test_insert_upsert_strict(fresh_db, method_name, strict):
+ table = fresh_db["t"]
+ method = getattr(table, method_name)
+ record = {"id": 1}
+ if method_name.endswith("_all"):
+ record = [record]
+ method(record, pk="id", strict=strict)
+ assert table.strict == strict or not fresh_db.supports_strict
+
+
[email protected]("strict", (False, True))
+def test_create_table_strict(fresh_db, strict):
+ table = fresh_db.create_table("t", {"id": int}, strict=strict)
+ assert table.strict == strict or not fresh_db.supports_strict
+
+
[email protected]("strict", (False, True))
+def test_create_strict(fresh_db, strict):
+ table = fresh_db["t"]
+ table.create({"id": int}, strict=strict)
+ assert table.strict == strict or not fresh_db.supports_strict
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/sqlite-utils-3.35.2/tests/test_lookup.py
new/sqlite-utils-3.36/tests/test_lookup.py
--- old/sqlite-utils-3.35.2/tests/test_lookup.py 2023-11-04
02:17:02.000000000 +0100
+++ new/sqlite-utils-3.36/tests/test_lookup.py 2023-12-08 06:36:09.000000000
+0100
@@ -151,3 +151,9 @@
columns=["name", "type"],
)
]
+
+
[email protected]("strict", (False, True))
+def test_lookup_new_table_strict(fresh_db, strict):
+ fresh_db["species"].lookup({"name": "Palm"}, strict=strict)
+ assert fresh_db["species"].strict == strict or not fresh_db.supports_strict
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/sqlite-utils-3.35.2/tests/test_transform.py
new/sqlite-utils-3.36/tests/test_transform.py
--- old/sqlite-utils-3.35.2/tests/test_transform.py 2023-11-04
02:17:02.000000000 +0100
+++ new/sqlite-utils-3.36/tests/test_transform.py 2023-12-08
06:36:09.000000000 +0100
@@ -530,3 +530,12 @@
tuple(row) for row in fresh_db.execute("select rowid, id, name from
places")
)
assert previous_rows == next_rows
+
+
[email protected]("strict", (False, True))
+def test_transform_strict(fresh_db, strict):
+ dogs = fresh_db.table("dogs", strict=strict)
+ dogs.insert({"id": 1, "name": "Cleo"})
+ assert dogs.strict == strict or not fresh_db.supports_strict
+ dogs.transform(not_null={"name"})
+ assert dogs.strict == strict or not fresh_db.supports_strict