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 <dmuel...@suse.com> + +- 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 +@click.option( + "--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 + + +@pytest.mark.parametrize("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 + + +@pytest.mark.parametrize("method", ("insert", "upsert")) +@pytest.mark.parametrize("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") + + +@pytest.mark.parametrize("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 + + +@pytest.mark.parametrize("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 + + +@pytest.mark.parametrize( + "method_name", ("insert", "upsert", "insert_all", "upsert_all") +) +@pytest.mark.parametrize("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 + + +@pytest.mark.parametrize("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 + + +@pytest.mark.parametrize("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"], ) ] + + +@pytest.mark.parametrize("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 + + +@pytest.mark.parametrize("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