mirror of
https://github.com/simonw/sqlite-utils.git
synced 2026-09-09 18:14:09 +02:00
parent
815b6a7d3d
commit
6225eba5c8
3 changed files with 35 additions and 0 deletions
|
|
@ -10,6 +10,7 @@ Unreleased
|
||||||
----------
|
----------
|
||||||
|
|
||||||
- JSON output from the command-line tool no longer escapes non-ASCII characters, so ``sqlite-utils data.db "select '日本語' as text"`` now outputs ``[{"text": "日本語"}]``. This matches how values were already stored by ``insert`` and how CSV/TSV output already behaved. A new ``--ascii`` option restores the previous behavior of escaping non-ASCII characters, for output destinations that cannot handle UTF-8 - see :ref:`cli_query_json_ascii`. The option is available on the ``query``, ``rows``, ``search``, ``tables``, ``views``, ``triggers``, ``indexes`` and ``memory`` commands. The ``convert --multi --dry-run`` preview and ``plugins`` output also no longer escape non-ASCII characters. (:issue:`625`)
|
- JSON output from the command-line tool no longer escapes non-ASCII characters, so ``sqlite-utils data.db "select '日本語' as text"`` now outputs ``[{"text": "日本語"}]``. This matches how values were already stored by ``insert`` and how CSV/TSV output already behaved. A new ``--ascii`` option restores the previous behavior of escaping non-ASCII characters, for output destinations that cannot handle UTF-8 - see :ref:`cli_query_json_ascii`. The option is available on the ``query``, ``rows``, ``search``, ``tables``, ``views``, ``triggers``, ``indexes`` and ``memory`` commands. The ``convert --multi --dry-run`` preview and ``plugins`` output also no longer escape non-ASCII characters. (:issue:`625`)
|
||||||
|
- ``table.insert_all(..., pk=...)`` now raises ``InvalidColumns`` if ``pk=`` names columns that do not exist in an existing table. Previously this behaved inconsistently, with single-row inserts raising a ``KeyError`` while other row counts succeeded. (:issue:`732`)
|
||||||
|
|
||||||
.. _v4_0rc3:
|
.. _v4_0rc3:
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4229,6 +4229,24 @@ class Table(Queryable):
|
||||||
if hash_id:
|
if hash_id:
|
||||||
pk = hash_id
|
pk = hash_id
|
||||||
|
|
||||||
|
if pk and not hash_id and self.exists():
|
||||||
|
pk_cols = [pk] if isinstance(pk, str) else list(pk)
|
||||||
|
existing_columns = self.columns_dict
|
||||||
|
missing_pk_cols = [
|
||||||
|
col
|
||||||
|
for col in pk_cols
|
||||||
|
if resolve_casing(col, existing_columns) not in existing_columns
|
||||||
|
]
|
||||||
|
if missing_pk_cols:
|
||||||
|
raise InvalidColumns(
|
||||||
|
"Invalid primary key column{} {} for table {} with columns {}".format(
|
||||||
|
"s" if len(missing_pk_cols) > 1 else "",
|
||||||
|
missing_pk_cols,
|
||||||
|
self.name,
|
||||||
|
list(existing_columns),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
if ignore and replace:
|
if ignore and replace:
|
||||||
raise ValueError("Use either ignore=True or replace=True, not both")
|
raise ValueError("Use either ignore=True or replace=True, not both")
|
||||||
all_columns = []
|
all_columns = []
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ from sqlite_utils.db import (
|
||||||
Database,
|
Database,
|
||||||
DescIndex,
|
DescIndex,
|
||||||
AlterError,
|
AlterError,
|
||||||
|
InvalidColumns,
|
||||||
NoObviousTable,
|
NoObviousTable,
|
||||||
OperationalError,
|
OperationalError,
|
||||||
ForeignKey,
|
ForeignKey,
|
||||||
|
|
@ -925,6 +926,21 @@ def test_insert_thousands_adds_extra_columns_after_first_100_with_alter(fresh_db
|
||||||
assert rows == [{"i": 101, "word": None, "extra": "Should trigger ALTER"}]
|
assert rows == [{"i": 101, "word": None, "extra": "Should trigger ALTER"}]
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("num_rows", (0, 1, 2, 3, 10))
|
||||||
|
def test_insert_all_pk_not_in_records_raises(fresh_db, num_rows):
|
||||||
|
# https://github.com/simonw/sqlite-utils/issues/732
|
||||||
|
fresh_db.conn.execute("CREATE TABLE t (a TEXT, b INT, PRIMARY KEY (a, b))")
|
||||||
|
rows = [{"a": "x{}".format(i), "b": i} for i in range(num_rows)]
|
||||||
|
|
||||||
|
with pytest.raises(InvalidColumns) as ex:
|
||||||
|
fresh_db["t"].insert_all(rows, pk="not_a_column", alter=True)
|
||||||
|
|
||||||
|
assert ex.value.args == (
|
||||||
|
"Invalid primary key column ['not_a_column'] for table t with columns ['a', 'b']",
|
||||||
|
)
|
||||||
|
assert fresh_db["t"].count == 0
|
||||||
|
|
||||||
|
|
||||||
def test_insert_ignore(fresh_db):
|
def test_insert_ignore(fresh_db):
|
||||||
fresh_db["test"].insert({"id": 1, "bar": 2}, pk="id")
|
fresh_db["test"].insert({"id": 1, "bar": 2}, pk="id")
|
||||||
# Should raise an error if we try this again
|
# Should raise an error if we try this again
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue