Skip to content

Commit

Permalink
Use REAL for floating point columns if table is strict, closes #644
Browse files Browse the repository at this point in the history
Refs #645
  • Loading branch information
simonw committed Nov 23, 2024
1 parent 7423296 commit 4dc2e2e
Show file tree
Hide file tree
Showing 4 changed files with 17 additions and 3 deletions.
3 changes: 3 additions & 0 deletions docs/python-api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1249,6 +1249,9 @@ If you pass a Python type, it will be mapped to SQLite types as shown here::
np.float32: "FLOAT"
np.float64: "FLOAT"

.. note::
In sqlite-utils 3.x ``FLOAT`` is used for floating point columns when the correct column type is actually ``REAL``. If you specify ``strict=True`` tables created in strict mode will use the correct column type of ``REAL`` instead. We plan to change this behavior in ``sqlite-utils`` 4.x to always use ``REAL``, but this will represent a minor breaking change and so is being held for the next major release, see issue :issue:`645`.

You can also add a column that is a foreign key reference to another table using the ``fk`` parameter:

.. code-block:: python
Expand Down
7 changes: 6 additions & 1 deletion sqlite_utils/db.py
Original file line number Diff line number Diff line change
Expand Up @@ -938,10 +938,15 @@ def sort_key(p):
other_column=foreign_keys_by_column[column_name].other_column,
)
)
column_type_str = COLUMN_TYPE_MAPPING[column_type]
# Special case for strict tables to map FLOAT to REAL
# Refs https://github.com/simonw/sqlite-utils/issues/644
if strict and column_type_str == "FLOAT":
column_type_str = "REAL"
column_defs.append(
" [{column_name}] {column_type}{column_extras}".format(
column_name=column_name,
column_type=COLUMN_TYPE_MAPPING[column_type],
column_type=column_type_str,
column_extras=(
(" " + " ".join(column_extras)) if column_extras else ""
),
Expand Down
4 changes: 3 additions & 1 deletion tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -2416,11 +2416,13 @@ def test_create_table_strict(strict):
db = Database("test.db")
result = runner.invoke(
cli.cli,
["create-table", "test.db", "items", "id", "integer"]
["create-table", "test.db", "items", "id", "integer", "w", "float"]
+ (["--strict"] if strict else []),
)
assert result.exit_code == 0
assert db["items"].strict == strict or not db.supports_strict
# Should have a floating point column
assert db["items"].columns_dict == {"id": int, "w": float}


@pytest.mark.parametrize("method", ("insert", "upsert"))
Expand Down
6 changes: 5 additions & 1 deletion tests/test_create.py
Original file line number Diff line number Diff line change
Expand Up @@ -1350,8 +1350,12 @@ def test_insert_upsert_strict(fresh_db, method_name, 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)
table = fresh_db.create_table("t", {"id": int, "f": float}, strict=strict)
assert table.strict == strict or not fresh_db.supports_strict
expected_schema = "CREATE TABLE [t] (\n" " [id] INTEGER,\n" " [f] FLOAT\n" ")"
if strict:
expected_schema = "CREATE TABLE [t] (\n [id] INTEGER,\n [f] REAL\n) STRICT"
assert table.schema == expected_schema


@pytest.mark.parametrize("strict", (False, True))
Expand Down

0 comments on commit 4dc2e2e

Please sign in to comment.