3
3
import urllib .parse
4
4
from enum import Enum
5
5
from functools import cached_property
6
- from operator import contains , eq
6
+ from operator import eq
7
7
from pathlib import Path
8
8
from typing import TYPE_CHECKING , Any , cast
9
9
13
13
from cryptography .hazmat .primitives import serialization
14
14
from singer_sdk import typing as th
15
15
from singer_sdk .connectors import SQLConnector
16
- from singer_sdk .connectors .sql import FullyQualifiedName
16
+ from singer_sdk .connectors .sql import FullyQualifiedName , JSONSchemaToSQL
17
17
from singer_sdk .exceptions import ConfigValidationError
18
18
from snowflake .sqlalchemy import URL
19
19
from snowflake .sqlalchemy .base import SnowflakeIdentifierPreparer
27
27
28
28
from sqlalchemy .engine import Engine
29
29
30
+ # TODO: Remove this when when JSON schema to SQL is stable
30
31
SNOWFLAKE_MAX_STRING_LENGTH = 16777216
31
32
32
33
@@ -89,6 +90,8 @@ class SnowflakeConnector(SQLConnector):
89
90
allow_merge_upsert : bool = False # Whether MERGE UPSERT is supported.
90
91
allow_temp_tables : bool = True # Whether temp tables are supported.
91
92
93
+ max_varchar_length = 16_777_216
94
+
92
95
def __init__ (self , * args : Any , ** kwargs : Any ) -> None :
93
96
self .table_cache : dict = {}
94
97
self .schema_cache : dict = {}
@@ -317,6 +320,16 @@ def _conform_max_length(jsonschema_type): # noqa: ANN205, ANN001
317
320
jsonschema_type ["maxLength" ] = SNOWFLAKE_MAX_STRING_LENGTH
318
321
return jsonschema_type
319
322
323
+ @cached_property
324
+ def jsonschema_to_sql (self ) -> JSONSchemaToSQL :
325
+ to_sql = super ().jsonschema_to_sql
326
+ to_sql .register_type_handler ("integer" , NUMBER )
327
+ to_sql .register_type_handler ("object" , VARIANT )
328
+ to_sql .register_type_handler ("array" , VARIANT )
329
+ to_sql .register_type_handler ("number" , sct .DOUBLE )
330
+ to_sql .register_format_handler ("date-time" , TIMESTAMP_NTZ )
331
+ return to_sql
332
+
320
333
def to_sql_type (self , jsonschema_type : dict ) -> sqlalchemy .types .TypeEngine :
321
334
"""Return a JSON Schema representation of the provided type.
322
335
@@ -336,23 +349,12 @@ def to_sql_type(self, jsonschema_type: dict) -> sqlalchemy.types.TypeEngine:
336
349
maxlength = jsonschema_type .get ("maxLength" , SNOWFLAKE_MAX_STRING_LENGTH )
337
350
# define type maps
338
351
string_submaps = [
339
- TypeMap (eq , TIMESTAMP_NTZ (), "date-time" ),
340
- TypeMap (contains , sqlalchemy .types .TIME (), "time" ),
341
- TypeMap (eq , sqlalchemy .types .DATE (), "date" ),
342
352
TypeMap (eq , sqlalchemy .types .VARCHAR (maxlength ), None ),
343
353
]
344
- type_maps = [
345
- TypeMap (th ._jsonschema_type_check , NUMBER (), ("integer" ,)), # noqa: SLF001
346
- TypeMap (th ._jsonschema_type_check , VARIANT (), ("object" ,)), # noqa: SLF001
347
- TypeMap (th ._jsonschema_type_check , VARIANT (), ("array" ,)), # noqa: SLF001
348
- TypeMap (th ._jsonschema_type_check , sct .DOUBLE (), ("number" ,)), # noqa: SLF001
349
- ]
350
354
# apply type maps
351
355
if th ._jsonschema_type_check (jsonschema_type , ("string" ,)): # noqa: SLF001
352
356
datelike_type = th .get_datelike_property_type (jsonschema_type )
353
357
target_type = evaluate_typemaps (string_submaps , datelike_type , target_type )
354
- else :
355
- target_type = evaluate_typemaps (type_maps , jsonschema_type , target_type )
356
358
357
359
return cast (sqlalchemy .types .TypeEngine , target_type )
358
360
0 commit comments