@@ -58,21 +58,26 @@ def build_location_helper(
58
58
database : str | None , schema : str | None , name : str , quote_identifiers : bool
59
59
) -> str :
60
60
"""Helper to format table/stage/file format's location."""
61
- if quote_identifiers :
62
- location = (
63
- (('"' + database + '".' ) if database else "" )
64
- + (('"' + schema + '".' ) if schema else "" )
65
- + ('"' + name + '"' )
66
- )
67
- else :
68
- location = (
69
- (database + "." if database else "" )
70
- + (schema + "." if schema else "" )
71
- + name
72
- )
61
+ location = (
62
+ (_escape_part_location (database , quote_identifiers ) + "." if database else "" )
63
+ + (_escape_part_location (schema , quote_identifiers ) + "." if schema else "" )
64
+ + _escape_part_location (name , quote_identifiers )
65
+ )
73
66
return location
74
67
75
68
69
+ def _escape_part_location (part : str , should_quote : bool ) -> str :
70
+ if "'" in part :
71
+ should_quote = True
72
+ if should_quote :
73
+ if not part .startswith ('"' ):
74
+ part = '"' + part
75
+ if not part .endswith ('"' ):
76
+ part = part + '"'
77
+
78
+ return part
79
+
80
+
76
81
def _do_create_temp_stage (
77
82
cursor : SnowflakeCursor ,
78
83
stage_location : str ,
@@ -473,6 +478,7 @@ def drop_object(name: str, object_type: str) -> None:
473
478
drop_sql = f"DROP { object_type .upper ()} IF EXISTS identifier(?) /* Python:snowflake.connector.pandas_tools.write_pandas() */"
474
479
params = (name ,)
475
480
logger .debug (f"dropping { object_type } with '{ drop_sql } '. params: %s" , params )
481
+
476
482
cursor .execute (
477
483
drop_sql ,
478
484
_is_internal = True ,
@@ -570,10 +576,11 @@ def drop_object(name: str, object_type: str) -> None:
570
576
num_statements = 1 ,
571
577
)
572
578
579
+ copy_stage_location = "@" + stage_location .replace ("'" , "\\ '" )
573
580
copy_into_sql = (
574
581
f"COPY INTO identifier(?) /* Python:snowflake.connector.pandas_tools.write_pandas() */ "
575
582
f"({ columns } ) "
576
- f"FROM (SELECT { parquet_columns } FROM @ { stage_location } ) "
583
+ f"FROM (SELECT { parquet_columns } FROM ' { copy_stage_location } ' ) "
577
584
f"FILE_FORMAT=("
578
585
f"TYPE=PARQUET "
579
586
f"COMPRESSION={ compression_map [compression ]} "
@@ -582,7 +589,10 @@ def drop_object(name: str, object_type: str) -> None:
582
589
f") "
583
590
f"PURGE=TRUE ON_ERROR=?"
584
591
)
585
- params = (target_table_location , on_error )
592
+ params = (
593
+ target_table_location ,
594
+ on_error ,
595
+ )
586
596
logger .debug (f"copying into with '{ copy_into_sql } '. params: %s" , params )
587
597
copy_results = cursor .execute (
588
598
copy_into_sql ,
0 commit comments