Improved column type introspection, closes #92

This commit is contained in:
Simon Willison 2020-03-14 13:04:06 -07:00
commit 1125460497
2 changed files with 21 additions and 14 deletions

View file

@ -1,4 +1,4 @@
from .utils import sqlite3, OperationalError, suggest_column_types
from .utils import sqlite3, OperationalError, suggest_column_types, column_affinity
from collections import namedtuple, OrderedDict
import datetime
import hashlib
@ -65,15 +65,6 @@ if np:
)
REVERSE_COLUMN_TYPE_MAPPING = {
"": str, # Columns in views sometimes have type = ''
"TEXT": str,
"BLOB": bytes,
"INTEGER": int,
"FLOAT": float,
}
class AlterError(Exception):
pass
@ -457,10 +448,7 @@ class Queryable:
@property
def columns_dict(self):
"Returns {column: python-type} dictionary"
return {
column.name: REVERSE_COLUMN_TYPE_MAPPING[column.type]
for column in self.columns
}
return {column.name: column_affinity(column.type) for column in self.columns}
@property
def schema(self):

View file

@ -33,3 +33,22 @@ def suggest_column_types(records):
t = str
column_types[key] = t
return column_types
def column_affinity(column_type):
# Implementation of SQLite affinity rules from
# https://www.sqlite.org/datatype3.html#determination_of_column_affinity
assert isinstance(column_type, str)
column_type = column_type.upper().strip()
if column_type == "":
return str # We differ from spec, which says it should be BLOB
if "INT" in column_type:
return int
if "CHAR" in column_type or "CLOB" in column_type or "TEXT" in column_type:
return str
if "BLOB" in column_type:
return bytes
if "REAL" in column_type or "FLOA" in column_type or "DOUB" in column_type:
return float
# Default is 'NUMERIC', which we currently also treat as float
return float