@@ -58,21 +58,27 @@ def build_location_helper(
5858 database : str | None , schema : str | None , name : str , quote_identifiers : bool
5959) -> str :
6060 """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+ )
7366 return location
7467
7568
69+ def _escape_part_location (part : str , should_quote : bool ) -> str :
70+ if "'" in part :
71+ part = part .replace ("'" , "\\ '" )
72+ should_quote = True
73+ if should_quote :
74+ if not part .startswith ('"' ):
75+ part = '"' + part
76+ if not part .endswith ('"' ):
77+ part = part + '"'
78+
79+ return part
80+
81+
7682def _do_create_temp_stage (
7783 cursor : SnowflakeCursor ,
7884 stage_location : str ,
@@ -440,18 +446,17 @@ def write_pandas(
440446 # Upload parquet file
441447 upload_sql = (
442448 "PUT /* Python:snowflake.connector.pandas_tools.write_pandas() */ "
443- "'file://{path}' '? ' PARALLEL={parallel}"
449+ "'file://{path}' '{stage_location} ' PARALLEL={parallel}"
444450 ).format (
445451 path = chunk_path .replace ("\\ " , "\\ \\ " ).replace ("'" , "\\ '" ),
452+ stage_location = "@" + stage_location ,
446453 parallel = parallel ,
447454 )
448- params = ("@" + stage_location ,)
449- logger .debug (f"uploading files with '{ upload_sql } ', params: %s" , params )
455+ logger .debug (f"uploading files with '{ upload_sql } '" )
450456 cursor .execute (
451457 upload_sql ,
452458 _is_internal = True ,
453459 _force_qmark_paramstyle = True ,
454- params = params ,
455460 num_statements = 1 ,
456461 )
457462 # Remove chunk file
@@ -571,9 +576,9 @@ def drop_object(name: str, object_type: str) -> None:
571576 )
572577
573578 copy_into_sql = (
574- f"COPY INTO identifier(? ) /* Python:snowflake.connector.pandas_tools.write_pandas() */ "
579+ f"COPY INTO identifier(' { target_table_location } ' ) /* Python:snowflake.connector.pandas_tools.write_pandas() */ "
575580 f"({ columns } ) "
576- f"FROM (SELECT { parquet_columns } FROM @{ stage_location } ) "
581+ f"FROM (SELECT { parquet_columns } FROM ' @{ stage_location } ' ) "
577582 f"FILE_FORMAT=("
578583 f"TYPE=PARQUET "
579584 f"COMPRESSION={ compression_map [compression ]} "
@@ -582,7 +587,7 @@ def drop_object(name: str, object_type: str) -> None:
582587 f") "
583588 f"PURGE=TRUE ON_ERROR=?"
584589 )
585- params = (target_table_location , on_error )
590+ params = (on_error , )
586591 logger .debug (f"copying into with '{ copy_into_sql } '. params: %s" , params )
587592 copy_results = cursor .execute (
588593 copy_into_sql ,
0 commit comments