Skip to content

Commit 40cb853

Browse files
committed
Use REAL not FLOAT as SQLite column type, refs #645
1 parent fb93452 commit 40cb853

File tree

8 files changed

+36
-31
lines changed

8 files changed

+36
-31
lines changed

docs/changelog.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ Unreleased
1010
----------
1111

1212
- The ``table.insert_all()`` and ``table.upsert_all()`` methods can now accept an iterator of lists or tuples as an alternative to dictionaries. The first item should be a list/tuple of column names. See :ref:`python_api_insert_lists` for details. (:issue:`672`)
13+
- **Breaking change:** The default floating point column type has been changed from ``FLOAT`` to ``REAL``, which is the correct SQLite type for floating point values. This affects auto-detected columns when inserting data. You can still explicitly specify ``"FLOAT"`` or ``"float"`` as a column type for backwards compatibility. (:issue:`645`)
1314

1415
.. _v4_0a0:
1516

docs/cli-reference.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -457,8 +457,8 @@ See :ref:`cli_transform_table`.
457457
--rename column2 column_renamed
458458

459459
Options:
460-
--type <TEXT CHOICE>... Change column type to INTEGER, TEXT, FLOAT or
461-
BLOB
460+
--type <TEXT CHOICE>... Change column type to INTEGER, TEXT, FLOAT,
461+
REAL or BLOB
462462
--drop TEXT Drop this column
463463
--rename <TEXT TEXT>... Rename this column to X
464464
-o, --column-order TEXT Reorder columns

docs/cli.rst

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1247,7 +1247,7 @@ To stop inserting after a specified number of records - useful for getting a fas
12471247
12481248
A progress bar is displayed when inserting data from a file. You can hide the progress bar using the ``--silent`` option.
12491249

1250-
By default every column inserted from a CSV or TSV file will be of type ``TEXT``. To automatically detect column types - resulting in a mix of ``TEXT``, ``INTEGER`` and ``FLOAT`` columns, use the ``--detect-types`` option (or its shortcut ``-d``).
1250+
By default every column inserted from a CSV or TSV file will be of type ``TEXT``. To automatically detect column types - resulting in a mix of ``TEXT``, ``INTEGER`` and ``REAL`` columns, use the ``--detect-types`` option (or its shortcut ``-d``).
12511251

12521252
For example, given a ``creatures.csv`` file containing this:
12531253

@@ -1274,7 +1274,7 @@ Will produce this schema:
12741274
CREATE TABLE "creatures" (
12751275
"name" TEXT,
12761276
"age" INTEGER,
1277-
"weight" FLOAT
1277+
"weight" REAL
12781278
);
12791279
12801280
You can set the ``SQLITE_UTILS_DETECT_TYPES`` environment variable if you want ``--detect-types`` to be the default behavior:
@@ -1589,7 +1589,7 @@ This will result in the following schema:
15891589
CREATE TABLE "images" (
15901590
"path" TEXT PRIMARY KEY,
15911591
"md5" TEXT,
1592-
"mtime" FLOAT
1592+
"mtime" REAL
15931593
);
15941594
15951595
Note that there's no ``content`` column here at all - if you specify custom columns using ``-c`` you need to include ``-c content`` to create that column.
@@ -1888,8 +1888,8 @@ The type of the returned values will be taken into account when creating the new
18881888
18891889
CREATE TABLE "places" (
18901890
"location" TEXT,
1891-
"latitude" FLOAT,
1892-
"longitude" FLOAT
1891+
"latitude" REAL,
1892+
"longitude" REAL
18931893
);
18941894
18951895
The code function can also return ``None``, in which case its output will be ignored. You can drop the original column at the end of the operation by adding ``--drop``.

docs/python-api.rst

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -548,7 +548,7 @@ This will create a table with the following schema:
548548
"id" INTEGER PRIMARY KEY,
549549
"name" TEXT,
550550
"age" INTEGER,
551-
"weight" FLOAT
551+
"weight" REAL
552552
)
553553
554554
.. _python_api_explicit_create:
@@ -1271,11 +1271,11 @@ You can specify the ``col_type`` argument either using a SQLite type as a string
12711271

12721272
The ``col_type`` is optional - if you omit it the type of ``TEXT`` will be used.
12731273

1274-
SQLite types you can specify are ``"TEXT"``, ``"INTEGER"``, ``"FLOAT"`` or ``"BLOB"``.
1274+
SQLite types you can specify are ``"TEXT"``, ``"INTEGER"``, ``"FLOAT"``, ``"REAL"`` or ``"BLOB"``.
12751275

12761276
If you pass a Python type, it will be mapped to SQLite types as shown here::
12771277

1278-
float: "FLOAT"
1278+
float: "REAL"
12791279
int: "INTEGER"
12801280
bool: "INTEGER"
12811281
str: "TEXT"
@@ -1294,12 +1294,12 @@ If you pass a Python type, it will be mapped to SQLite types as shown here::
12941294
np.uint16: "INTEGER"
12951295
np.uint32: "INTEGER"
12961296
np.uint64: "INTEGER"
1297-
np.float16: "FLOAT"
1298-
np.float32: "FLOAT"
1299-
np.float64: "FLOAT"
1297+
np.float16: "REAL"
1298+
np.float32: "REAL"
1299+
np.float64: "REAL"
13001300

13011301
.. note::
1302-
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`.
1302+
In sqlite-utils 4.0 the default floating point column type was changed from ``FLOAT`` to ``REAL``, which is the correct SQLite type for floating point columns. You can still explicitly specify ``"FLOAT"`` or ``"float"`` as a column type for backwards compatibility, but auto-detected floating point columns will now use ``REAL``. See issue :issue:`645`.
13031303

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

sqlite_utils/cli.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444

4545
CONTEXT_SETTINGS = dict(help_option_names=["-h", "--help"])
4646

47-
VALID_COLUMN_TYPES = ("INTEGER", "TEXT", "FLOAT", "BLOB")
47+
VALID_COLUMN_TYPES = ("INTEGER", "TEXT", "FLOAT", "REAL", "BLOB")
4848

4949
UNICODE_ERROR = """
5050
{}
@@ -2425,10 +2425,12 @@ def schema(
24252425
"--type",
24262426
type=(
24272427
str,
2428-
click.Choice(["INTEGER", "TEXT", "FLOAT", "BLOB"], case_sensitive=False),
2428+
click.Choice(
2429+
["INTEGER", "TEXT", "FLOAT", "REAL", "BLOB"], case_sensitive=False
2430+
),
24292431
),
24302432
multiple=True,
2431-
help="Change column type to INTEGER, TEXT, FLOAT or BLOB",
2433+
help="Change column type to INTEGER, TEXT, FLOAT, REAL or BLOB",
24322434
)
24332435
@click.option("--drop", type=str, multiple=True, help="Drop this column")
24342436
@click.option(

sqlite_utils/db.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ class Default:
189189
DEFAULT = Default()
190190

191191
COLUMN_TYPE_MAPPING = {
192-
float: "FLOAT",
192+
float: "REAL",
193193
int: "INTEGER",
194194
bool: "INTEGER",
195195
str: "TEXT",
@@ -203,19 +203,21 @@ class Default:
203203
datetime.date: "TEXT",
204204
datetime.time: "TEXT",
205205
datetime.timedelta: "TEXT",
206-
decimal.Decimal: "FLOAT",
206+
decimal.Decimal: "REAL",
207207
None.__class__: "TEXT",
208208
uuid.UUID: "TEXT",
209209
# SQLite explicit types
210210
"TEXT": "TEXT",
211211
"INTEGER": "INTEGER",
212212
"FLOAT": "FLOAT",
213+
"REAL": "REAL",
213214
"BLOB": "BLOB",
214215
"text": "TEXT",
215216
"str": "TEXT",
216217
"integer": "INTEGER",
217218
"int": "INTEGER",
218219
"float": "FLOAT",
220+
"real": "REAL",
219221
"blob": "BLOB",
220222
"bytes": "BLOB",
221223
}
@@ -232,9 +234,9 @@ class Default:
232234
np.uint16: "INTEGER",
233235
np.uint32: "INTEGER",
234236
np.uint64: "INTEGER",
235-
np.float16: "FLOAT",
236-
np.float32: "FLOAT",
237-
np.float64: "FLOAT",
237+
np.float16: "REAL",
238+
np.float32: "REAL",
239+
np.float64: "REAL",
238240
}
239241
)
240242
except AttributeError:

tests/test_cli_convert.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -408,7 +408,7 @@ def test_convert_multi_complex_column_types(fresh_db_and_path):
408408
assert db["rows"].schema == (
409409
'CREATE TABLE "rows" (\n'
410410
' "id" INTEGER PRIMARY KEY\n'
411-
', "is_str" TEXT, "is_float" FLOAT, "is_int" INTEGER, "is_bytes" BLOB)'
411+
', "is_str" TEXT, "is_float" REAL, "is_int" INTEGER, "is_bytes" BLOB)'
412412
)
413413

414414

tests/test_create.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ def test_create_table(fresh_db):
4343
assert ["test_table"] == fresh_db.table_names()
4444
assert [
4545
{"name": "text_col", "type": "TEXT"},
46-
{"name": "float_col", "type": "FLOAT"},
46+
{"name": "float_col", "type": "REAL"},
4747
{"name": "int_col", "type": "INTEGER"},
4848
{"name": "bool_col", "type": "INTEGER"},
4949
{"name": "bytes_col", "type": "BLOB"},
@@ -52,7 +52,7 @@ def test_create_table(fresh_db):
5252
assert (
5353
'CREATE TABLE "test_table" (\n'
5454
' "text_col" TEXT,\n'
55-
' "float_col" FLOAT,\n'
55+
' "float_col" REAL,\n'
5656
' "int_col" INTEGER,\n'
5757
' "bool_col" INTEGER,\n'
5858
' "bytes_col" BLOB,\n'
@@ -143,7 +143,7 @@ def test_create_table_with_not_null(fresh_db):
143143
[{"name": "create", "type": "TEXT"}, {"name": "table", "type": "TEXT"}],
144144
),
145145
({"day": datetime.time(11, 0)}, [{"name": "day", "type": "TEXT"}]),
146-
({"decimal": decimal.Decimal("1.2")}, [{"name": "decimal", "type": "FLOAT"}]),
146+
({"decimal": decimal.Decimal("1.2")}, [{"name": "decimal", "type": "REAL"}]),
147147
(
148148
{"memoryview": memoryview(b"hello")},
149149
[{"name": "memoryview", "type": "BLOB"}],
@@ -193,7 +193,7 @@ def test_create_table_with_custom_columns(method_name, use_old_upsert):
193193
{"name": "id", "type": "INTEGER"},
194194
{"name": "name", "type": "TEXT"},
195195
{"name": "age", "type": "INTEGER"},
196-
{"name": "weight", "type": "FLOAT"},
196+
{"name": "weight", "type": "REAL"},
197197
]
198198
assert expected_columns == [
199199
{"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):
357357
"weight",
358358
float,
359359
None,
360-
'CREATE TABLE "dogs" (\n "name" TEXT\n, "weight" FLOAT)',
360+
'CREATE TABLE "dogs" (\n "name" TEXT\n, "weight" REAL)',
361361
),
362362
("text", "TEXT", None, 'CREATE TABLE "dogs" (\n "name" TEXT\n, "text" TEXT)'),
363363
(
@@ -561,7 +561,7 @@ def test_index_foreign_keys_if_index_name_is_already_used(fresh_db):
561561
),
562562
(
563563
{"hats": 5, "rating": 3.5},
564-
[{"name": "hats", "type": "INTEGER"}, {"name": "rating", "type": "FLOAT"}],
564+
[{"name": "hats", "type": "INTEGER"}, {"name": "rating", "type": "REAL"}],
565565
),
566566
],
567567
)
@@ -1197,7 +1197,7 @@ def test_create(fresh_db):
11971197
assert fresh_db["t"].schema == (
11981198
'CREATE TABLE "t" (\n'
11991199
' "id" INTEGER PRIMARY KEY,\n'
1200-
' "float" FLOAT NOT NULL,\n'
1200+
' "float" REAL NOT NULL,\n'
12011201
' "text" TEXT,\n'
12021202
' "integer" INTEGER NOT NULL DEFAULT 0,\n'
12031203
' "bytes" BLOB\n'
@@ -1360,7 +1360,7 @@ def test_insert_upsert_strict(fresh_db, method_name, strict):
13601360
def test_create_table_strict(fresh_db, strict):
13611361
table = fresh_db.create_table("t", {"id": int, "f": float}, strict=strict)
13621362
assert table.strict == strict or not fresh_db.supports_strict
1363-
expected_schema = 'CREATE TABLE "t" (\n' ' "id" INTEGER,\n' ' "f" FLOAT\n' ")"
1363+
expected_schema = 'CREATE TABLE "t" (\n' ' "id" INTEGER,\n' ' "f" REAL\n' ")"
13641364
if strict and not fresh_db.supports_strict:
13651365
return
13661366
if strict:

0 commit comments

Comments
 (0)