Skip to content
This repository was archived by the owner on May 5, 2022. It is now read-only.

Commit e8cbcfa

Browse files
committed
refactor: move datatype to a separated module
1 parent 4d749cf commit e8cbcfa

File tree

3 files changed

+79
-77
lines changed

3 files changed

+79
-77
lines changed

sqlalchemy_trino/compiler.py

Lines changed: 1 addition & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,4 @@
1-
import re
2-
3-
from sqlalchemy import util
4-
from sqlalchemy.sql import compiler, sqltypes
5-
from sqlalchemy.sql.type_api import TypeEngine
1+
from sqlalchemy.sql import compiler
62

73
# https://trino.io/docs/current/language/reserved.html
84
RESERVED_WORDS = {
@@ -79,77 +75,6 @@
7975
"with",
8076
}
8177

82-
# https://trino.io/docs/current/language/types.html
83-
_type_map = {
84-
# === Boolean ===
85-
'boolean': sqltypes.BOOLEAN,
86-
87-
# === Integer ===
88-
'tinyint': sqltypes.SMALLINT,
89-
'smallint': sqltypes.SMALLINT,
90-
'integer': sqltypes.INTEGER,
91-
'bigint': sqltypes.BIGINT,
92-
93-
# === Floating-point ===
94-
'real': sqltypes.FLOAT,
95-
'double': sqltypes.FLOAT,
96-
97-
# === Fixed-precision ===
98-
'decimal': sqltypes.DECIMAL,
99-
100-
# === String ===
101-
'varchar': sqltypes.VARCHAR,
102-
'char': sqltypes.CHAR,
103-
'varbinary': sqltypes.VARBINARY,
104-
'json': sqltypes.JSON,
105-
106-
# === Date and time ===
107-
'date': sqltypes.DATE,
108-
'time': sqltypes.Time,
109-
'time with time zone': sqltypes.Time,
110-
'timestamp': sqltypes.TIMESTAMP,
111-
'timestamp with time zone': sqltypes.TIMESTAMP,
112-
113-
# 'interval year to month': IntervalOfYear, # TODO
114-
'interval day to second': sqltypes.Interval,
115-
116-
# === Structural ===
117-
'array': sqltypes.ARRAY,
118-
# 'map': MAP
119-
# 'row': ROW
120-
121-
# === Mixed ===
122-
# 'ipaddress': IPADDRESS
123-
# 'uuid': UUID,
124-
# 'hyperloglog': HYPERLOGLOG,
125-
# 'p4hyperloglog': P4HYPERLOGLOG,
126-
# 'qdigest': QDIGEST,
127-
# 'tdigest': TDIGEST,
128-
}
129-
130-
131-
def parse_sqltype(type_str: str, column: str) -> TypeEngine:
132-
type_str = type_str.lower()
133-
m = re.match(r'^([\w\s]+)(?:\(([\d,\s]*)\))?', type_str)
134-
if m is None:
135-
util.warn(f"Could not parse type name '{type_str}'")
136-
return sqltypes.NULLTYPE
137-
type_name, type_opts = m.groups() # type: str, str
138-
type_name = type_name.strip()
139-
if type_name not in _type_map:
140-
util.warn(f"Did not recognize type '{type_name}' of column '{column}'")
141-
return sqltypes.NULLTYPE
142-
type_class = _type_map[type_name]
143-
type_args = [int(o.strip()) for o in type_opts.split(',')] if type_opts else []
144-
if type_name in ('time', 'timestamp'):
145-
type_kwargs = dict(timezone=type_str.endswith("with time zone"))
146-
# TODO: handle time/timestamp(p) precision
147-
return type_class(**type_kwargs)
148-
if type_name in ('array', 'map', 'row'):
149-
# TODO
150-
return sqltypes.NULLTYPE
151-
return type_class(*type_args)
152-
15378

15479
class TrinoSQLCompiler(compiler.SQLCompiler):
15580
pass

sqlalchemy_trino/datatype.py

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
import re
2+
3+
from sqlalchemy import util
4+
from sqlalchemy.sql import sqltypes
5+
from sqlalchemy.sql.type_api import TypeEngine
6+
7+
# https://trino.io/docs/current/language/types.html
8+
_type_map = {
9+
# === Boolean ===
10+
'boolean': sqltypes.BOOLEAN,
11+
12+
# === Integer ===
13+
'tinyint': sqltypes.SMALLINT,
14+
'smallint': sqltypes.SMALLINT,
15+
'integer': sqltypes.INTEGER,
16+
'bigint': sqltypes.BIGINT,
17+
18+
# === Floating-point ===
19+
'real': sqltypes.FLOAT,
20+
'double': sqltypes.FLOAT,
21+
22+
# === Fixed-precision ===
23+
'decimal': sqltypes.DECIMAL,
24+
25+
# === String ===
26+
'varchar': sqltypes.VARCHAR,
27+
'char': sqltypes.CHAR,
28+
'varbinary': sqltypes.VARBINARY,
29+
'json': sqltypes.JSON,
30+
31+
# === Date and time ===
32+
'date': sqltypes.DATE,
33+
'time': sqltypes.Time,
34+
'time with time zone': sqltypes.Time,
35+
'timestamp': sqltypes.TIMESTAMP,
36+
'timestamp with time zone': sqltypes.TIMESTAMP,
37+
38+
# 'interval year to month': IntervalOfYear, # TODO
39+
'interval day to second': sqltypes.Interval,
40+
41+
# === Structural ===
42+
'array': sqltypes.ARRAY,
43+
# 'map': MAP
44+
# 'row': ROW
45+
46+
# === Mixed ===
47+
# 'ipaddress': IPADDRESS
48+
# 'uuid': UUID,
49+
# 'hyperloglog': HYPERLOGLOG,
50+
# 'p4hyperloglog': P4HYPERLOGLOG,
51+
# 'qdigest': QDIGEST,
52+
# 'tdigest': TDIGEST,
53+
}
54+
55+
56+
def parse_sqltype(type_str: str, column: str) -> TypeEngine:
57+
type_str = type_str.lower()
58+
m = re.match(r'^([\w\s]+)(?:\(([\d,\s]*)\))?', type_str)
59+
if m is None:
60+
util.warn(f"Could not parse type name '{type_str}'")
61+
return sqltypes.NULLTYPE
62+
type_name, type_opts = m.groups() # type: str, str
63+
type_name = type_name.strip()
64+
if type_name not in _type_map:
65+
util.warn(f"Did not recognize type '{type_name}' of column '{column}'")
66+
return sqltypes.NULLTYPE
67+
type_class = _type_map[type_name]
68+
type_args = [int(o.strip()) for o in type_opts.split(',')] if type_opts else []
69+
if type_name in ('time', 'timestamp'):
70+
type_kwargs = dict(timezone=type_str.endswith("with time zone"))
71+
# TODO: handle time/timestamp(p) precision
72+
return type_class(**type_kwargs)
73+
if type_name in ('array', 'map', 'row'):
74+
# TODO
75+
return sqltypes.NULLTYPE
76+
return type_class(*type_args)

sqlalchemy_trino/dialect.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
from trino.auth import BasicAuthentication
99

1010
from . import compiler
11+
from . import datatype
1112
from . import dbapi as trino_dbapi
1213
from . import error
1314
from . import result
@@ -96,7 +97,7 @@ def get_columns(self, connection: Connection,
9697
for row in rows:
9798
columns.append(dict(
9899
name=row.Column,
99-
type=compiler.parse_sqltype(row.Type, row.Column),
100+
type=datatype.parse_sqltype(row.Type, row.Column),
100101
nullable=getattr(row, 'Null', True),
101102
default=None,
102103
))

0 commit comments

Comments
 (0)