Skip to content

Commit fea2527

Browse files
committed
Types: Improve type mappings
- Consequently use upper-case type definitions from `sqlalchemy.types` - Add `timestamp without time zone` types (scalar and array) - On SQLAlchemy 2, map `real` and `double{_precision}` types to the newly introduced `sqltypes.{DOUBLE,DOUBLE_PRECISION}` types All of this is intended to improve reverse type lookups / reflections.
1 parent 07bba7b commit fea2527

File tree

3 files changed

+44
-27
lines changed

3 files changed

+44
-27
lines changed

docs/inspection-reflection.rst

+2-2
Original file line numberDiff line numberDiff line change
@@ -87,10 +87,10 @@ Create a SQLAlchemy table object:
8787
Reflect column data types from the table metadata:
8888

8989
>>> table.columns.get('name')
90-
Column('name', String(), table=<characters>)
90+
Column('name', VARCHAR(), table=<characters>)
9191

9292
>>> table.primary_key
93-
PrimaryKeyConstraint(Column('id', String(), table=<characters>, primary_key=True...
93+
PrimaryKeyConstraint(Column('id', VARCHAR(), table=<characters>, primary_key=True...
9494

9595

9696
CrateDialect

src/sqlalchemy_cratedb/dialect.py

+34-23
Original file line numberDiff line numberDiff line change
@@ -36,40 +36,51 @@
3636
from .type import ObjectArray, ObjectType
3737

3838
TYPES_MAP = {
39-
"boolean": sqltypes.Boolean,
40-
"short": sqltypes.SmallInteger,
41-
"smallint": sqltypes.SmallInteger,
39+
"boolean": sqltypes.BOOLEAN,
40+
"short": sqltypes.SMALLINT,
41+
"smallint": sqltypes.SMALLINT,
4242
"timestamp": sqltypes.TIMESTAMP,
4343
"timestamp with time zone": sqltypes.TIMESTAMP,
44+
"timestamp without time zone": sqltypes.TIMESTAMP,
4445
"object": ObjectType,
45-
"integer": sqltypes.Integer,
46-
"long": sqltypes.NUMERIC,
47-
"bigint": sqltypes.NUMERIC,
46+
"object_array": ObjectArray, # TODO: Can this also be improved to use `sqltypes.ARRAY`?
47+
"integer": sqltypes.INTEGER,
48+
"long": sqltypes.BIGINT,
49+
"bigint": sqltypes.BIGINT,
50+
"float": sqltypes.FLOAT,
4851
"double": sqltypes.DECIMAL,
4952
"double precision": sqltypes.DECIMAL,
50-
"object_array": ObjectArray,
51-
"float": sqltypes.Float,
52-
"real": sqltypes.Float,
53-
"string": sqltypes.String,
54-
"text": sqltypes.String
53+
"real": sqltypes.REAL,
54+
"string": sqltypes.VARCHAR,
55+
"text": sqltypes.VARCHAR,
5556
}
5657
try:
5758
# SQLAlchemy >= 1.1
5859
from sqlalchemy.types import ARRAY
59-
TYPES_MAP["integer_array"] = ARRAY(sqltypes.Integer)
60-
TYPES_MAP["boolean_array"] = ARRAY(sqltypes.Boolean)
61-
TYPES_MAP["short_array"] = ARRAY(sqltypes.SmallInteger)
62-
TYPES_MAP["smallint_array"] = ARRAY(sqltypes.SmallInteger)
60+
TYPES_MAP["integer_array"] = ARRAY(sqltypes.INTEGER)
61+
TYPES_MAP["boolean_array"] = ARRAY(sqltypes.BOOLEAN)
62+
TYPES_MAP["short_array"] = ARRAY(sqltypes.SMALLINT)
63+
TYPES_MAP["smallint_array"] = ARRAY(sqltypes.SMALLINT)
6364
TYPES_MAP["timestamp_array"] = ARRAY(sqltypes.TIMESTAMP)
6465
TYPES_MAP["timestamp with time zone_array"] = ARRAY(sqltypes.TIMESTAMP)
65-
TYPES_MAP["long_array"] = ARRAY(sqltypes.NUMERIC)
66-
TYPES_MAP["bigint_array"] = ARRAY(sqltypes.NUMERIC)
67-
TYPES_MAP["double_array"] = ARRAY(sqltypes.DECIMAL)
68-
TYPES_MAP["double precision_array"] = ARRAY(sqltypes.DECIMAL)
69-
TYPES_MAP["float_array"] = ARRAY(sqltypes.Float)
70-
TYPES_MAP["real_array"] = ARRAY(sqltypes.Float)
71-
TYPES_MAP["string_array"] = ARRAY(sqltypes.String)
72-
TYPES_MAP["text_array"] = ARRAY(sqltypes.String)
66+
TYPES_MAP["timestamp without time zone_array"] = ARRAY(sqltypes.TIMESTAMP)
67+
TYPES_MAP["long_array"] = ARRAY(sqltypes.BIGINT)
68+
TYPES_MAP["bigint_array"] = ARRAY(sqltypes.BIGINT)
69+
TYPES_MAP["float_array"] = ARRAY(sqltypes.FLOAT)
70+
TYPES_MAP["real_array"] = ARRAY(sqltypes.REAL)
71+
TYPES_MAP["string_array"] = ARRAY(sqltypes.VARCHAR)
72+
TYPES_MAP["text_array"] = ARRAY(sqltypes.VARCHAR)
73+
except Exception:
74+
pass
75+
try:
76+
# SQLAlchemy >= 2.0
77+
from sqlalchemy.types import DOUBLE, DOUBLE_PRECISION
78+
TYPES_MAP["real"] = DOUBLE
79+
TYPES_MAP["real_array"] = ARRAY(DOUBLE)
80+
TYPES_MAP["double"] = DOUBLE
81+
TYPES_MAP["double_array"] = ARRAY(DOUBLE)
82+
TYPES_MAP["double precision"] = DOUBLE_PRECISION
83+
TYPES_MAP["double precision_array"] = ARRAY(DOUBLE_PRECISION)
7384
except Exception:
7485
pass
7586

tests/integration.py

+8-2
Original file line numberDiff line numberDiff line change
@@ -176,16 +176,22 @@ def create_test_suite():
176176
'docs/crud.rst',
177177
'docs/working-with-types.rst',
178178
'docs/advanced-querying.rst',
179-
'docs/inspection-reflection.rst',
180179
]
181180

182-
# Don't run DataFrame integration tests on SQLAlchemy 1.3 and Python 3.7.
181+
# Don't run DataFrame integration tests on SQLAlchemy 1.3 or Python 3.7.
183182
skip_dataframe = SA_VERSION < SA_1_4 or sys.version_info < (3, 8)
184183
if not skip_dataframe:
185184
sqlalchemy_integration_tests += [
186185
'docs/dataframe.rst',
187186
]
188187

188+
# Don't run reflection integration tests on SQLAlchemy 1.3 and Python 3.10 and 3.11.
189+
skip_reflection = SA_VERSION < SA_1_4 and (3, 10) <= sys.version_info < (3, 12)
190+
if not skip_reflection:
191+
sqlalchemy_integration_tests += [
192+
'docs/inspection-reflection.rst',
193+
]
194+
189195
s = doctest.DocFileSuite(
190196
*sqlalchemy_integration_tests,
191197
module_relative=False,

0 commit comments

Comments
 (0)