|
34 | 34 | )
|
35 | 35 | from snowflake.connector.aio._result_set import ResultSet, ResultSetIterator
|
36 | 36 | from snowflake.connector.constants import (
|
| 37 | + CMD_TYPE_DOWNLOAD, |
| 38 | + CMD_TYPE_UPLOAD, |
37 | 39 | PARAMETER_PYTHON_CONNECTOR_QUERY_RESULT_FORMAT,
|
38 | 40 | QueryStatus,
|
39 | 41 | )
|
@@ -1043,6 +1045,153 @@ async def get_result_batches(self) -> list[ResultBatch] | None:
|
1043 | 1045 | )
|
1044 | 1046 | return self._result_set.batches
|
1045 | 1047 |
|
| 1048 | + async def _download( |
| 1049 | + self, |
| 1050 | + stage_location: str, |
| 1051 | + target_directory: str, |
| 1052 | + options: dict[str, Any], |
| 1053 | + _do_reset: bool = True, |
| 1054 | + ) -> None: |
| 1055 | + """Downloads from the stage location to the target directory. |
| 1056 | +
|
| 1057 | + Args: |
| 1058 | + stage_location (str): The location of the stage to download from. |
| 1059 | + target_directory (str): The destination directory to download into. |
| 1060 | + options (dict[str, Any]): The download options. |
| 1061 | + _do_reset (bool, optional): Whether to reset the cursor before |
| 1062 | + downloading, by default we will reset the cursor. |
| 1063 | + """ |
| 1064 | + from ._file_transfer_agent import SnowflakeFileTransferAgent |
| 1065 | + |
| 1066 | + if _do_reset: |
| 1067 | + self.reset() |
| 1068 | + |
| 1069 | + # Interpret the file operation. |
| 1070 | + ret = self.connection._file_operation_parser.parse_file_operation( |
| 1071 | + stage_location=stage_location, |
| 1072 | + local_file_name=None, |
| 1073 | + target_directory=target_directory, |
| 1074 | + command_type=CMD_TYPE_DOWNLOAD, |
| 1075 | + options=options, |
| 1076 | + ) |
| 1077 | + |
| 1078 | + # Execute the file operation based on the interpretation above. |
| 1079 | + file_transfer_agent = SnowflakeFileTransferAgent( |
| 1080 | + self, |
| 1081 | + "", # empty command because it is triggered by directly calling this util not by a SQL query |
| 1082 | + ret, |
| 1083 | + ) |
| 1084 | + await file_transfer_agent.execute() |
| 1085 | + await self._init_result_and_meta(file_transfer_agent.result()) |
| 1086 | + |
| 1087 | + async def _upload( |
| 1088 | + self, |
| 1089 | + local_file_name: str, |
| 1090 | + stage_location: str, |
| 1091 | + options: dict[str, Any], |
| 1092 | + _do_reset: bool = True, |
| 1093 | + ) -> None: |
| 1094 | + """Uploads the local file to the stage location. |
| 1095 | +
|
| 1096 | + Args: |
| 1097 | + local_file_name (str): The local file to be uploaded. |
| 1098 | + stage_location (str): The stage location to upload the local file to. |
| 1099 | + options (dict[str, Any]): The upload options. |
| 1100 | + _do_reset (bool, optional): Whether to reset the cursor before |
| 1101 | + uploading, by default we will reset the cursor. |
| 1102 | + """ |
| 1103 | + from ._file_transfer_agent import SnowflakeFileTransferAgent |
| 1104 | + |
| 1105 | + if _do_reset: |
| 1106 | + self.reset() |
| 1107 | + |
| 1108 | + # Interpret the file operation. |
| 1109 | + ret = self.connection._file_operation_parser.parse_file_operation( |
| 1110 | + stage_location=stage_location, |
| 1111 | + local_file_name=local_file_name, |
| 1112 | + target_directory=None, |
| 1113 | + command_type=CMD_TYPE_UPLOAD, |
| 1114 | + options=options, |
| 1115 | + ) |
| 1116 | + |
| 1117 | + # Execute the file operation based on the interpretation above. |
| 1118 | + file_transfer_agent = SnowflakeFileTransferAgent( |
| 1119 | + self, |
| 1120 | + "", # empty command because it is triggered by directly calling this util not by a SQL query |
| 1121 | + ret, |
| 1122 | + ) |
| 1123 | + await file_transfer_agent.execute() |
| 1124 | + await self._init_result_and_meta(file_transfer_agent.result()) |
| 1125 | + |
| 1126 | + async def _download_stream( |
| 1127 | + self, stage_location: str, decompress: bool = False |
| 1128 | + ) -> IO[bytes]: |
| 1129 | + """Downloads from the stage location as a stream. |
| 1130 | +
|
| 1131 | + Args: |
| 1132 | + stage_location (str): The location of the stage to download from. |
| 1133 | + decompress (bool, optional): Whether to decompress the file, by |
| 1134 | + default we do not decompress. |
| 1135 | +
|
| 1136 | + Returns: |
| 1137 | + IO[bytes]: A stream to read from. |
| 1138 | + """ |
| 1139 | + # Interpret the file operation. |
| 1140 | + ret = self.connection._file_operation_parser.parse_file_operation( |
| 1141 | + stage_location=stage_location, |
| 1142 | + local_file_name=None, |
| 1143 | + target_directory=None, |
| 1144 | + command_type=CMD_TYPE_DOWNLOAD, |
| 1145 | + options=None, |
| 1146 | + has_source_from_stream=True, |
| 1147 | + ) |
| 1148 | + |
| 1149 | + # Set up stream downloading based on the interpretation and return the stream for reading. |
| 1150 | + return await self.connection._stream_downloader.download_as_stream( |
| 1151 | + ret, decompress |
| 1152 | + ) |
| 1153 | + |
| 1154 | + async def _upload_stream( |
| 1155 | + self, |
| 1156 | + input_stream: IO[bytes], |
| 1157 | + stage_location: str, |
| 1158 | + options: dict[str, Any], |
| 1159 | + _do_reset: bool = True, |
| 1160 | + ) -> None: |
| 1161 | + """Uploads content in the input stream to the stage location. |
| 1162 | +
|
| 1163 | + Args: |
| 1164 | + input_stream (IO[bytes]): A stream to read from. |
| 1165 | + stage_location (str): The location of the stage to upload to. |
| 1166 | + options (dict[str, Any]): The upload options. |
| 1167 | + _do_reset (bool, optional): Whether to reset the cursor before |
| 1168 | + uploading, by default we will reset the cursor. |
| 1169 | + """ |
| 1170 | + from ._file_transfer_agent import SnowflakeFileTransferAgent |
| 1171 | + |
| 1172 | + if _do_reset: |
| 1173 | + self.reset() |
| 1174 | + |
| 1175 | + # Interpret the file operation. |
| 1176 | + ret = self.connection._file_operation_parser.parse_file_operation( |
| 1177 | + stage_location=stage_location, |
| 1178 | + local_file_name=None, |
| 1179 | + target_directory=None, |
| 1180 | + command_type=CMD_TYPE_UPLOAD, |
| 1181 | + options=options, |
| 1182 | + has_source_from_stream=input_stream, |
| 1183 | + ) |
| 1184 | + |
| 1185 | + # Execute the file operation based on the interpretation above. |
| 1186 | + file_transfer_agent = SnowflakeFileTransferAgent( |
| 1187 | + self, |
| 1188 | + "", # empty command because it is triggered by directly calling this util not by a SQL query |
| 1189 | + ret, |
| 1190 | + source_from_stream=input_stream, |
| 1191 | + ) |
| 1192 | + await file_transfer_agent.execute() |
| 1193 | + await self._init_result_and_meta(file_transfer_agent.result()) |
| 1194 | + |
1046 | 1195 | async def get_results_from_sfqid(self, sfqid: str) -> None:
|
1047 | 1196 | """Gets the results from previously ran query. This methods differs from ``SnowflakeCursor.query_result``
|
1048 | 1197 | in that it monitors the ``sfqid`` until it is no longer running, and then retrieves the results.
|
|
0 commit comments