I like the idea of sqlite’s manifest typing / type affinity:
http://www.sqlite.org/datatype3.html
Essentially, if I set a column’s affinity as ‘numeric’, it will duck type integers or floats to store them as such, but still allow me to store strings if I want to. Seems to me this is the best ‘default’ type for a column when i’m not sure ahead of time of what data i want to store in it.
so off i go:
metadata = MetaData()
new_table = Table(table_name, metadata )
for col_name in column_headings:
new_table.append_column(Column(col_name,
sqlite.NUMERIC, #this should duck-type numbers but can handle strings as well
primary_key=col_name in primary_key_columns))
new_table.create(self.engine, checkfirst=False)
but when i try and store some string values, eg “abc” in the table, sqlalchemy falls over:
File "[...]\sqlalchemy\processors.py", line 79, in to_float
return float(value)
ValueError: invalid literal for float(): abc
Boo, hiss. So, is there any way I can convince sqlalchemy to let sqlite do the typing? perhaps i can use a type from sqlalchemy.types instead of sqlachemy.dialects.sqlite?
[edit:] for bonus points: i need to be able to access tables via introspection / reflection. so some kind of way of having this work with meta.reflect() would be great! 😉
OK, here’s what I’ve come up with:
Define a custom column type, as per
http://www.sqlalchemy.org/docs/reference/sqlalchemy/types.html#custom-types
a combination of the documentation and some trial & error have given me this:
The current sqlalchemy dialect type returns to_float in bind_processor, which is why I was getting the errors before. i.m.v.v.h.o., this is a bug.
for my bonus points: manually setting column type to MyDuckType in my metadata.reflect() code:
seems to work for me. Any suggestions / improvements?