Use REAL not FLOAT as SQLite column type (#680)

* Use REAL not FLOAT as SQLite column type, refs #645
* Fix for REAL columns by CSV --detect-types

Refs https://github.com/simonw/sqlite-utils/issues/645#issuecomment-3568947189

* Removed note about strict and REAL
This commit is contained in:
Simon Willison 2025-11-23 21:37:59 -08:00 committed by GitHub
commit c872d27bb3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 61 additions and 37 deletions

View file

@ -284,7 +284,7 @@ def test_create_index_desc(db_path):
"int",
'CREATE TABLE "dogs" (\n "name" TEXT\n, "integer" INTEGER)',
),
("float", "FLOAT", 'CREATE TABLE "dogs" (\n "name" TEXT\n, "float" FLOAT)'),
("float", "FLOAT", 'CREATE TABLE "dogs" (\n "name" TEXT\n, "float" REAL)'),
("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)'),
@ -2240,6 +2240,28 @@ def test_upsert_detect_types(tmpdir, option):
]
def test_csv_detect_types_creates_real_columns(tmpdir):
"""Test that CSV import with --detect-types creates REAL columns for floats"""
db_path = str(tmpdir / "test.db")
data = "name,age,weight\nCleo,6,45.5\nDori,1,3.5"
result = CliRunner().invoke(
cli.cli,
["insert", db_path, "creatures", "-", "--csv", "--detect-types"],
catch_exceptions=False,
input=data,
)
assert result.exit_code == 0
db = Database(db_path)
# Check that the schema uses REAL for the weight column
assert db["creatures"].schema == (
'CREATE TABLE "creatures" (\n'
' "name" TEXT,\n'
' "age" INTEGER,\n'
' "weight" REAL\n'
")"
)
def test_integer_overflow_error(tmpdir):
db_path = str(tmpdir / "test.db")
result = CliRunner().invoke(

View file

@ -408,7 +408,7 @@ def test_convert_multi_complex_column_types(fresh_db_and_path):
assert db["rows"].schema == (
'CREATE TABLE "rows" (\n'
' "id" INTEGER PRIMARY KEY\n'
', "is_str" TEXT, "is_float" FLOAT, "is_int" INTEGER, "is_bytes" BLOB)'
', "is_str" TEXT, "is_float" REAL, "is_int" INTEGER, "is_bytes" BLOB)'
)

View file

@ -43,7 +43,7 @@ def test_create_table(fresh_db):
assert ["test_table"] == fresh_db.table_names()
assert [
{"name": "text_col", "type": "TEXT"},
{"name": "float_col", "type": "FLOAT"},
{"name": "float_col", "type": "REAL"},
{"name": "int_col", "type": "INTEGER"},
{"name": "bool_col", "type": "INTEGER"},
{"name": "bytes_col", "type": "BLOB"},
@ -52,7 +52,7 @@ def test_create_table(fresh_db):
assert (
'CREATE TABLE "test_table" (\n'
' "text_col" TEXT,\n'
' "float_col" FLOAT,\n'
' "float_col" REAL,\n'
' "int_col" INTEGER,\n'
' "bool_col" INTEGER,\n'
' "bytes_col" BLOB,\n'
@ -143,7 +143,7 @@ def test_create_table_with_not_null(fresh_db):
[{"name": "create", "type": "TEXT"}, {"name": "table", "type": "TEXT"}],
),
({"day": datetime.time(11, 0)}, [{"name": "day", "type": "TEXT"}]),
({"decimal": decimal.Decimal("1.2")}, [{"name": "decimal", "type": "FLOAT"}]),
({"decimal": decimal.Decimal("1.2")}, [{"name": "decimal", "type": "REAL"}]),
(
{"memoryview": memoryview(b"hello")},
[{"name": "memoryview", "type": "BLOB"}],
@ -193,7 +193,7 @@ def test_create_table_with_custom_columns(method_name, use_old_upsert):
{"name": "id", "type": "INTEGER"},
{"name": "name", "type": "TEXT"},
{"name": "age", "type": "INTEGER"},
{"name": "weight", "type": "FLOAT"},
{"name": "weight", "type": "REAL"},
]
assert expected_columns == [
{"name": col.name, "type": col.type} for col in table.columns
@ -357,7 +357,7 @@ def test_create_error_if_invalid_self_referential_foreign_keys(fresh_db):
"weight",
float,
None,
'CREATE TABLE "dogs" (\n "name" TEXT\n, "weight" FLOAT)',
'CREATE TABLE "dogs" (\n "name" TEXT\n, "weight" REAL)',
),
("text", "TEXT", None, 'CREATE TABLE "dogs" (\n "name" TEXT\n, "text" TEXT)'),
(
@ -561,7 +561,7 @@ def test_index_foreign_keys_if_index_name_is_already_used(fresh_db):
),
(
{"hats": 5, "rating": 3.5},
[{"name": "hats", "type": "INTEGER"}, {"name": "rating", "type": "FLOAT"}],
[{"name": "hats", "type": "INTEGER"}, {"name": "rating", "type": "REAL"}],
),
],
)
@ -1197,7 +1197,7 @@ def test_create(fresh_db):
assert fresh_db["t"].schema == (
'CREATE TABLE "t" (\n'
' "id" INTEGER PRIMARY KEY,\n'
' "float" FLOAT NOT NULL,\n'
' "float" REAL NOT NULL,\n'
' "text" TEXT,\n'
' "integer" INTEGER NOT NULL DEFAULT 0,\n'
' "bytes" BLOB\n'
@ -1360,7 +1360,7 @@ def test_insert_upsert_strict(fresh_db, method_name, strict):
def test_create_table_strict(fresh_db, 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' ")"
expected_schema = 'CREATE TABLE "t" (\n' ' "id" INTEGER,\n' ' "f" REAL\n' ")"
if strict and not fresh_db.supports_strict:
return
if strict: