mirror of
https://github.com/simonw/sqlite-utils.git
synced 2026-07-25 10:24:32 +02:00
transform: coerce empty strings to NULL when converting TEXT columns to numeric types
When a TEXT column is transformed to INTEGER, FLOAT, or REAL and a row contains an empty string, the empty string is now converted to NULL during the INSERT...SELECT copy, matching the expected behavior described in #488. Fixes #488
This commit is contained in:
parent
a947dc6739
commit
58f5aeb37f
2 changed files with 40 additions and 4 deletions
|
|
@ -2856,6 +2856,19 @@ class Table(Queryable):
|
|||
).strip()
|
||||
)
|
||||
|
||||
# Columns being changed from TEXT to a numeric type: coerce empty strings to NULL
|
||||
_numeric_sql_types = {"INTEGER", "REAL", "FLOAT", "NUMERIC"}
|
||||
text_to_numeric_cols = {
|
||||
col_name
|
||||
for col_name, new_type in types.items()
|
||||
if existing_columns.get(col_name) == str
|
||||
and COLUMN_TYPE_MAPPING.get(
|
||||
new_type,
|
||||
new_type.upper() if isinstance(new_type, str) else "",
|
||||
)
|
||||
in _numeric_sql_types
|
||||
}
|
||||
|
||||
# Copy across data, respecting any renamed columns
|
||||
new_cols = []
|
||||
old_cols = []
|
||||
|
|
@ -2866,10 +2879,16 @@ class Table(Queryable):
|
|||
if "rowid" not in new_cols:
|
||||
new_cols.insert(0, "rowid")
|
||||
old_cols.insert(0, "rowid")
|
||||
|
||||
def _copy_expr(col):
|
||||
if col in text_to_numeric_cols:
|
||||
return "NULLIF({}, '')".format(quote_identifier(col))
|
||||
return quote_identifier(col)
|
||||
|
||||
copy_sql = "INSERT INTO {} ({new_cols})\n SELECT {old_cols} FROM {};".format(
|
||||
quote_identifier(new_table_name),
|
||||
quote_identifier(self.name),
|
||||
old_cols=", ".join(quote_identifier(col) for col in old_cols),
|
||||
old_cols=", ".join(_copy_expr(col) for col in old_cols),
|
||||
new_cols=", ".join(quote_identifier(col) for col in new_cols),
|
||||
)
|
||||
sqls.append(copy_sql)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue