e6data-python-connector 2.3.14__py3-none-any.whl → 2.3.15__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -148,6 +148,13 @@ _type_map = {
148
148
  'struct': types.String,
149
149
  'uniontype': types.String,
150
150
  'decimal': E6dataDecimal,
151
+ 'numeric': E6dataDecimal,
152
+ # aliases for the short type names the e6data engine actually emits
153
+ 'int': types.Integer,
154
+ 'long': types.BigInteger,
155
+ 'short': types.SmallInteger,
156
+ 'bool': types.Boolean,
157
+ 'real': types.Float,
151
158
  }
152
159
 
153
160
 
@@ -328,7 +335,17 @@ class E6dataDialect(default.DefaultDialect):
328
335
  row = dict()
329
336
  row["name"] = column.get('fieldName')
330
337
  field_type = str(column.get('fieldType')).lower()
331
- row["type"] = _type_map.get(field_type, types.String)
338
+ # Engine types may carry parameters: 'decimal(7,2)', 'varchar(16)',
339
+ # 'array<int>'. Strip them so the base type maps; otherwise the exact
340
+ # key lookup misses and the column silently defaults to String.
341
+ base_type = field_type.split('(', 1)[0].split('<', 1)[0].strip()
342
+ mapped = _type_map.get(base_type)
343
+ if mapped is None:
344
+ _logger.warning(
345
+ "e6data dialect: unmapped column type %r -> defaulting to String",
346
+ column.get('fieldType'))
347
+ mapped = types.String
348
+ row["type"] = mapped
332
349
  rows.append(row)
333
350
  return rows
334
351
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: e6data-python-connector
3
- Version: 2.3.14
3
+ Version: 2.3.15
4
4
  Summary: Client for the e6data distributed SQL Engine.
5
5
  Home-page: https://github.com/e6x-labs/e6data-python-connector
6
6
  Author: e6data, Inc.
@@ -39,7 +39,7 @@ Dynamic: summary
39
39
 
40
40
  # e6data Python Connector
41
41
 
42
- ![version](https://img.shields.io/badge/version-2.3.14-blue.svg)
42
+ ![version](https://img.shields.io/badge/version-2.3.15-blue.svg)
43
43
 
44
44
  ## Introduction
45
45
 
@@ -5,7 +5,7 @@ e6data_python_connector/connection_pool.py,sha256=Gzr3z4tJJV4cKUYWdyRqVtmJEvh6ZF
5
5
  e6data_python_connector/constants.py,sha256=AwACS9iUaYj84oRRHj9Waep9LGbNHxcE07BABV7s45Y,1406
6
6
  e6data_python_connector/datainputstream.py,sha256=DittJuNzTAVUiQ0ZzSFSfMnFC7YuHieF0YqjYt2dpZU,28187
7
7
  e6data_python_connector/date_time_utils.py,sha256=0n_3CchQTvXUHFIqWcenng9sW0l2A6sPLcDny_chDME,21283
8
- e6data_python_connector/dialect.py,sha256=yqtfWpS6JE-yDylysR9TzUTpT3kRHn6Rr94h2WifEoQ,12078
8
+ e6data_python_connector/dialect.py,sha256=f-LrzauT0IdrbK965w2sLgd5OHv5L_hmzntyBJsc1A8,12883
9
9
  e6data_python_connector/e6data_grpc.py,sha256=AwTuRauFiZjIrAIpHdX87JcBxGSVee2-R1PsRN6gbSk,63747
10
10
  e6data_python_connector/exceptions.py,sha256=vrUqdzMq3LjbCmvr5_TcRq9eKmdqGfe-uVjR0BJQf5U,382
11
11
  e6data_python_connector/strategy.py,sha256=whAC-C031XFirP71hXKqdiMTJRIUUEvc34tuo2W8k-0,6539
@@ -53,7 +53,7 @@ test/test_connection_pool_e2e.py,sha256=UdqFbiFRY93tnp7DBR68CwZKfXD-gxiZH47qG2Ap
53
53
  test/test_current_implementation.py,sha256=2tbLsfzzsiopVrwaNfUqbOzZzPmC6S0M3M2kFR-mZ-I,4295
54
54
  test/test_decimal128_binary_parsing.py,sha256=eAtIvy8IvZszxhz9EoJET7-YA4KbY6IZAcIpsSmu6rQ,6512
55
55
  test/test_decimal128_parsing.py,sha256=ODSG4337GaWL0kdaQig5XQvmlSFnBkqhIat7Cs9VchI,9644
56
- test/test_dialect_columns.py,sha256=KdlPDVm2oITcSGL7WtGExn-Z76g0L4wgLK5hKGpo5Vk,2841
56
+ test/test_dialect_columns.py,sha256=EDMBKi-DyUf_lDZWF8EiqghvkHatReYjiq9R_Ql2jL0,4482
57
57
  test/test_fix.py,sha256=d53VIY6oXpkn1SZGCi7xM2nRC_JveLkUouHa8CSOJDE,820
58
58
  test/test_improved_parsing.py,sha256=dWVpGjnfi_PWdZEV1vM8Ps5n0YvDM04VGM708fKBSUM,4001
59
59
  test/test_known_case.py,sha256=q4CVeU1ht3y_zWrdkZrvGHhU7zE5hNN91NMZVfdBZ_c,1854
@@ -77,9 +77,9 @@ test/tests_grpc.py,sha256=VRqJwW2BVRpL3c0BnwCKvtowogAS_0JYa1Ss4ynqTss,5916
77
77
  test/validate_decimal128.py,sha256=8m7FFD3nOHFkPKpN1kCd5MDDzfeEEJnMnOoSeXmX_I0,3320
78
78
  test/validate_implementation.py,sha256=2keEodBGxztdG1kgavTq-p-cLw1L9UNQLkXTfIijBNQ,5569
79
79
  test/verify_decimal_fix.py,sha256=n7XUV4dbo7kTdx-mVqhha9Nr6_bkDudwplHTdV-rM_Y,1051
80
- e6data_python_connector-2.3.14.dist-info/LICENSE,sha256=WNHhf_5RCaeuKWyq_K39vmp9F28LxKsB4SpomwSZ2L0,11357
81
- e6data_python_connector-2.3.14.dist-info/METADATA,sha256=shgSca_ESgKD_FBBP05Fv3cQ7yA2XI0pwxPdmMa72UA,27193
82
- e6data_python_connector-2.3.14.dist-info/WHEEL,sha256=jB7zZ3N9hIM9adW7qlTAyycLYW9npaWKLRzaoVcLKcM,91
83
- e6data_python_connector-2.3.14.dist-info/entry_points.txt,sha256=MDK4cAOND0preLvq2Tlpnz00wXnP_Y_UopqJsAf3U7Y,77
84
- e6data_python_connector-2.3.14.dist-info/top_level.txt,sha256=nGwT_-fOD03WiucD15uscVhsUR42BzvBM2ddlnAMS4A,36
85
- e6data_python_connector-2.3.14.dist-info/RECORD,,
80
+ e6data_python_connector-2.3.15.dist-info/LICENSE,sha256=WNHhf_5RCaeuKWyq_K39vmp9F28LxKsB4SpomwSZ2L0,11357
81
+ e6data_python_connector-2.3.15.dist-info/METADATA,sha256=KX_EQB6Gxp36F6CSJn0rJGJh4AZwTJknmQeK5VyydAQ,27193
82
+ e6data_python_connector-2.3.15.dist-info/WHEEL,sha256=jB7zZ3N9hIM9adW7qlTAyycLYW9npaWKLRzaoVcLKcM,91
83
+ e6data_python_connector-2.3.15.dist-info/entry_points.txt,sha256=MDK4cAOND0preLvq2Tlpnz00wXnP_Y_UopqJsAf3U7Y,77
84
+ e6data_python_connector-2.3.15.dist-info/top_level.txt,sha256=nGwT_-fOD03WiucD15uscVhsUR42BzvBM2ddlnAMS4A,36
85
+ e6data_python_connector-2.3.15.dist-info/RECORD,,
@@ -82,5 +82,37 @@ class TestDialectGetColumns(unittest.TestCase):
82
82
  self.assertIs(columns[0]["type"], types.String)
83
83
 
84
84
 
85
+ def test_get_columns_maps_engine_short_names_and_parameterized_types(self):
86
+ # The e6data engine emits short names ('int') and parameterized types
87
+ # ('decimal(7,2)', 'varchar(16)', 'array<int>'). These must resolve to the
88
+ # right SQLAlchemy type, not silently default to String.
89
+ client = FakeClient([
90
+ {"fieldName": "sk", "fieldType": "int"},
91
+ {"fieldName": "big", "fieldType": "long"},
92
+ {"fieldName": "small", "fieldType": "short"},
93
+ {"fieldName": "flag", "fieldType": "bool"},
94
+ {"fieldName": "price", "fieldType": "decimal(7,2)"},
95
+ {"fieldName": "name", "fieldType": "varchar(16)"},
96
+ {"fieldName": "code", "fieldType": "char(1)"},
97
+ {"fieldName": "tags", "fieldType": "array<int>"},
98
+ ])
99
+ connection = FakeSQLAlchemyConnection(client)
100
+ dialect = E6dataDialect()
101
+ dialect.catalog_name = "lakehouse"
102
+
103
+ with patch.object(dialect_module, "Connection", FakeSQLAlchemyConnection):
104
+ columns = dialect.get_columns(connection, "items", "sales")
105
+
106
+ by_name = {c["name"]: c["type"] for c in columns}
107
+ self.assertIs(by_name["sk"], types.Integer)
108
+ self.assertIs(by_name["big"], types.BigInteger)
109
+ self.assertIs(by_name["small"], types.SmallInteger)
110
+ self.assertIs(by_name["flag"], types.Boolean)
111
+ self.assertIs(by_name["price"], E6dataDecimal)
112
+ self.assertIs(by_name["name"], types.String)
113
+ self.assertIs(by_name["code"], types.String)
114
+ self.assertIs(by_name["tags"], types.String) # complex type normalizes, not a miss
115
+
116
+
85
117
  if __name__ == "__main__":
86
118
  unittest.main()