2626from snowflake .connector .telemetry import TelemetryData , TelemetryField
2727from snowflake .connector .util_text import random_string
2828
29+ from ._utils import (
30+ _PYTHON_SNOWPARK_USE_SCOPED_TEMP_OBJECTS_STRING ,
31+ TempObjectType ,
32+ get_temp_type_for_object ,
33+ random_name_for_temp_object ,
34+ )
2935from .cursor import SnowflakeCursor
3036
3137if TYPE_CHECKING : # pragma: no cover
@@ -77,8 +83,9 @@ def _do_create_temp_stage(
7783 compression : str ,
7884 auto_create_table : bool ,
7985 overwrite : bool ,
86+ use_scoped_temp_object : bool ,
8087) -> None :
81- create_stage_sql = f"CREATE TEMP STAGE /* Python:snowflake.connector.pandas_tools.write_pandas() */ { stage_location } FILE_FORMAT=(TYPE=PARQUET COMPRESSION={ compression } { ' BINARY_AS_TEXT=FALSE' if auto_create_table or overwrite else '' } )"
88+ create_stage_sql = f"CREATE { get_temp_type_for_object ( use_scoped_temp_object ) } STAGE /* Python:snowflake.connector.pandas_tools.write_pandas() */ { stage_location } FILE_FORMAT=(TYPE=PARQUET COMPRESSION={ compression } { ' BINARY_AS_TEXT=FALSE' if auto_create_table or overwrite else '' } )"
8289 logger .debug (f"creating stage with '{ create_stage_sql } '" )
8390 cursor .execute (create_stage_sql , _is_internal = True ).fetchall ()
8491
@@ -91,8 +98,13 @@ def _create_temp_stage(
9198 compression : str ,
9299 auto_create_table : bool ,
93100 overwrite : bool ,
101+ use_scoped_temp_object : bool = False ,
94102) -> str :
95- stage_name = random_string ()
103+ stage_name = (
104+ random_name_for_temp_object (TempObjectType .STAGE )
105+ if use_scoped_temp_object
106+ else random_string ()
107+ )
96108 stage_location = build_location_helper (
97109 database = database ,
98110 schema = schema ,
@@ -101,7 +113,12 @@ def _create_temp_stage(
101113 )
102114 try :
103115 _do_create_temp_stage (
104- cursor , stage_location , compression , auto_create_table , overwrite
116+ cursor ,
117+ stage_location ,
118+ compression ,
119+ auto_create_table ,
120+ overwrite ,
121+ use_scoped_temp_object ,
105122 )
106123 except ProgrammingError as e :
107124 # User may not have the privilege to create stage on the target schema, so fall back to use current schema as
@@ -111,7 +128,12 @@ def _create_temp_stage(
111128 )
112129 stage_location = stage_name
113130 _do_create_temp_stage (
114- cursor , stage_location , compression , auto_create_table , overwrite
131+ cursor ,
132+ stage_location ,
133+ compression ,
134+ auto_create_table ,
135+ overwrite ,
136+ use_scoped_temp_object ,
115137 )
116138
117139 return stage_location
@@ -122,9 +144,10 @@ def _do_create_temp_file_format(
122144 file_format_location : str ,
123145 compression : str ,
124146 sql_use_logical_type : str ,
147+ use_scoped_temp_object : bool ,
125148) -> None :
126149 file_format_sql = (
127- f"CREATE TEMP FILE FORMAT { file_format_location } "
150+ f"CREATE { get_temp_type_for_object ( use_scoped_temp_object ) } FILE FORMAT { file_format_location } "
128151 f"/* Python:snowflake.connector.pandas_tools.write_pandas() */ "
129152 f"TYPE=PARQUET COMPRESSION={ compression } { sql_use_logical_type } "
130153 )
@@ -139,8 +162,13 @@ def _create_temp_file_format(
139162 quote_identifiers : bool ,
140163 compression : str ,
141164 sql_use_logical_type : str ,
165+ use_scoped_temp_object : bool = False ,
142166) -> str :
143- file_format_name = random_string ()
167+ file_format_name = (
168+ random_name_for_temp_object (TempObjectType .FILE_FORMAT )
169+ if use_scoped_temp_object
170+ else random_string ()
171+ )
144172 file_format_location = build_location_helper (
145173 database = database ,
146174 schema = schema ,
@@ -149,7 +177,11 @@ def _create_temp_file_format(
149177 )
150178 try :
151179 _do_create_temp_file_format (
152- cursor , file_format_location , compression , sql_use_logical_type
180+ cursor ,
181+ file_format_location ,
182+ compression ,
183+ sql_use_logical_type ,
184+ use_scoped_temp_object ,
153185 )
154186 except ProgrammingError as e :
155187 # User may not have the privilege to create file format on the target schema, so fall back to use current schema
@@ -159,7 +191,11 @@ def _create_temp_file_format(
159191 )
160192 file_format_location = file_format_name
161193 _do_create_temp_file_format (
162- cursor , file_format_location , compression , sql_use_logical_type
194+ cursor ,
195+ file_format_location ,
196+ compression ,
197+ sql_use_logical_type ,
198+ use_scoped_temp_object ,
163199 )
164200
165201 return file_format_location
@@ -263,6 +299,14 @@ def write_pandas(
263299 f"Invalid compression '{ compression } ', only acceptable values are: { compression_map .keys ()} "
264300 )
265301
302+ _use_scoped_temp_object = (
303+ conn ._session_parameters .get (
304+ _PYTHON_SNOWPARK_USE_SCOPED_TEMP_OBJECTS_STRING , False
305+ )
306+ if conn ._session_parameters
307+ else False
308+ )
309+
266310 if create_temp_table :
267311 warnings .warn (
268312 "create_temp_table is deprecated, we still respect this parameter when it is True but "
@@ -324,6 +368,7 @@ def write_pandas(
324368 compression ,
325369 auto_create_table ,
326370 overwrite ,
371+ _use_scoped_temp_object ,
327372 )
328373
329374 with TemporaryDirectory () as tmp_folder :
@@ -370,6 +415,7 @@ def drop_object(name: str, object_type: str) -> None:
370415 quote_identifiers ,
371416 compression_map [compression ],
372417 sql_use_logical_type ,
418+ _use_scoped_temp_object ,
373419 )
374420 infer_schema_sql = f"SELECT COLUMN_NAME, TYPE FROM table(infer_schema(location=>'@{ stage_location } ', file_format=>'{ file_format_location } '))"
375421 logger .debug (f"inferring schema with '{ infer_schema_sql } '" )
0 commit comments