fakesnow 0.9.23__py3-none-any.whl → 0.9.24__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
fakesnow/conn.py CHANGED
@@ -1,13 +1,11 @@
1
1
  from __future__ import annotations
2
2
 
3
- import json
4
3
  import os
5
4
  from collections.abc import Iterable
6
5
  from pathlib import Path
7
6
  from types import TracebackType
8
7
  from typing import Any
9
8
 
10
- import pandas as pd
11
9
  import snowflake.connector.converter
12
10
  import snowflake.connector.errors
13
11
  import sqlglot
@@ -147,29 +145,3 @@ class FakeSnowflakeConnection:
147
145
 
148
146
  def rollback(self) -> None:
149
147
  self.cursor().execute("ROLLBACK")
150
-
151
- def _insert_df(self, df: pd.DataFrame, table_name: str) -> int:
152
- # Objects in dataframes are written as parquet structs, and snowflake loads parquet structs as json strings.
153
- # Whereas duckdb analyses a dataframe see https://duckdb.org/docs/api/python/data_ingestion.html#pandas-dataframes--object-columns
154
- # and converts a object to the most specific type possible, eg: dict -> STRUCT, MAP or varchar, and list -> LIST
155
- # For dicts see https://github.com/duckdb/duckdb/pull/3985 and https://github.com/duckdb/duckdb/issues/9510
156
- #
157
- # When the rows have dicts with different keys there isn't a single STRUCT that can cover them, so the type is
158
- # varchar and value a string containing a struct representation. In order to support dicts with different keys
159
- # we first convert the dicts to json strings. A pity we can't do something inside duckdb and avoid the dataframe
160
- # copy and transform in python.
161
-
162
- df = df.copy()
163
-
164
- # Identify columns of type object
165
- object_cols = df.select_dtypes(include=["object"]).columns
166
-
167
- # Apply json.dumps to these columns
168
- for col in object_cols:
169
- # don't jsonify string
170
- df[col] = df[col].apply(lambda x: json.dumps(x) if isinstance(x, (dict, list)) else x)
171
-
172
- escaped_cols = ",".join(f'"{col}"' for col in df.columns.to_list())
173
- self._duck_conn.execute(f"INSERT INTO {table_name}({escaped_cols}) SELECT * FROM df")
174
-
175
- return self._duck_conn.fetchall()[0][0]
fakesnow/cursor.py CHANGED
@@ -26,9 +26,11 @@ import fakesnow.transforms as transforms
26
26
  from fakesnow.types import describe_as_result_metadata
27
27
 
28
28
  if TYPE_CHECKING:
29
+ # don't require pandas at import time
29
30
  import pandas as pd
30
31
  import pyarrow.lib
31
32
 
33
+ # avoid circular import
32
34
  from fakesnow.conn import FakeSnowflakeConnection
33
35
 
34
36
 
fakesnow/pandas_tools.py CHANGED
@@ -1,14 +1,18 @@
1
1
  from __future__ import annotations
2
2
 
3
+ import json
3
4
  from collections.abc import Sequence
4
5
  from typing import TYPE_CHECKING, Any, Literal, Optional
5
6
 
6
7
  import numpy as np
8
+ from duckdb import DuckDBPyConnection
9
+
10
+ from fakesnow.conn import FakeSnowflakeConnection
7
11
 
8
12
  if TYPE_CHECKING:
13
+ # don't require pandas at import time
9
14
  import pandas as pd
10
15
 
11
- from fakesnow.conn import FakeSnowflakeConnection
12
16
 
13
17
  CopyResult = tuple[
14
18
  str,
@@ -68,10 +72,37 @@ def write_pandas(
68
72
 
69
73
  conn.cursor().execute(f"CREATE TABLE IF NOT EXISTS {name} ({','.join(cols)})")
70
74
 
71
- count = conn._insert_df(df, name) # noqa: SLF001
75
+ count = _insert_df(conn._duck_conn, df, name) # noqa: SLF001
72
76
 
73
77
  # mocks https://docs.snowflake.com/en/sql-reference/sql/copy-into-table.html#output
74
78
  mock_copy_results = [("fakesnow/file0.txt", "LOADED", count, count, 1, 0, None, None, None, None)]
75
79
 
76
80
  # return success
77
81
  return (True, len(mock_copy_results), count, mock_copy_results)
82
+
83
+
84
+ def _insert_df(duck_conn: DuckDBPyConnection, df: pd.DataFrame, table_name: str) -> int:
85
+ # Objects in dataframes are written as parquet structs, and snowflake loads parquet structs as json strings.
86
+ # Whereas duckdb analyses a dataframe see https://duckdb.org/docs/api/python/data_ingestion.html#pandas-dataframes--object-columns
87
+ # and converts a object to the most specific type possible, eg: dict -> STRUCT, MAP or varchar, and list -> LIST
88
+ # For dicts see https://github.com/duckdb/duckdb/pull/3985 and https://github.com/duckdb/duckdb/issues/9510
89
+ #
90
+ # When the rows have dicts with different keys there isn't a single STRUCT that can cover them, so the type is
91
+ # varchar and value a string containing a struct representation. In order to support dicts with different keys
92
+ # we first convert the dicts to json strings. A pity we can't do something inside duckdb and avoid the dataframe
93
+ # copy and transform in python.
94
+
95
+ df = df.copy()
96
+
97
+ # Identify columns of type object
98
+ object_cols = df.select_dtypes(include=["object"]).columns
99
+
100
+ # Apply json.dumps to these columns
101
+ for col in object_cols:
102
+ # don't jsonify string
103
+ df[col] = df[col].apply(lambda x: json.dumps(x) if isinstance(x, (dict, list)) else x)
104
+
105
+ escaped_cols = ",".join(f'"{col}"' for col in df.columns.to_list())
106
+ duck_conn.execute(f"INSERT INTO {table_name}({escaped_cols}) SELECT * FROM df")
107
+
108
+ return duck_conn.fetchall()[0][0]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: fakesnow
3
- Version: 0.9.23
3
+ Version: 0.9.24
4
4
  Summary: Fake Snowflake Connector for Python. Run, mock and test Snowflake DB locally.
5
5
  License: Apache License
6
6
  Version 2.0, January 2004
@@ -3,23 +3,23 @@ fakesnow/__main__.py,sha256=GDrGyNTvBFuqn_UfDjKs7b3LPtU6gDv1KwosVDrukIM,76
3
3
  fakesnow/arrow.py,sha256=WLkr1nEiNxUcPdzadKSM33sRAiQJsN6LvuzTVIsi3D0,2766
4
4
  fakesnow/checks.py,sha256=-QMvdcrRbhN60rnzxLBJ0IkUBWyLR8gGGKKmCS0w9mA,2383
5
5
  fakesnow/cli.py,sha256=9qfI-Ssr6mo8UmIlXkUAOz2z2YPBgDsrEVaZv9FjGFs,2201
6
- fakesnow/conn.py,sha256=yR9SMGSKkLvdPfi5fDwj9PQggOrPcKkdBBnQy2y_Bak,6921
7
- fakesnow/cursor.py,sha256=lITuMMy_hA9_riC121Sv9bFDFbU9BP9NlOLdHlP0ahY,19371
6
+ fakesnow/conn.py,sha256=Gy_Z7BZRm5yMjV3x6hR4iegDQFdG9aJBjqWdc3iWYFU,5353
7
+ fakesnow/cursor.py,sha256=2PtW9hzfXs3mzv6BBxXLoS-pPtD4otrfQ2KnPNNanGI,19441
8
8
  fakesnow/expr.py,sha256=CAxuYIUkwI339DQIBzvFF0F-m1tcVGKEPA5rDTzmH9A,892
9
9
  fakesnow/fakes.py,sha256=JQTiUkkwPeQrJ8FDWhPFPK6pGwd_aR2oiOrNzCWznlM,187
10
10
  fakesnow/fixtures.py,sha256=G-NkVeruSQAJ7fvSS2fR2oysUn0Yra1pohHlOvacKEk,455
11
11
  fakesnow/info_schema.py,sha256=DObVOrhzppAFHsdtj4YI9oRISn9SkJUG6ONjVleQQ_Y,6303
12
12
  fakesnow/instance.py,sha256=3cJvPRuFy19dMKXbtBLl6imzO48pEw8uTYhZyFDuwhk,3133
13
13
  fakesnow/macros.py,sha256=pX1YJDnQOkFJSHYUjQ6ErEkYIKvFI6Ncz_au0vv1csA,265
14
- fakesnow/pandas_tools.py,sha256=ecL0kxIVU5o2--P3bRLWWVhxXqq6Km4trFr36txukMg,1897
14
+ fakesnow/pandas_tools.py,sha256=WjyjTV8QUCQQaCGboaEOvx2uo4BkknpWYjtLwkeCY6U,3468
15
15
  fakesnow/py.typed,sha256=B-DLSjYBi7pkKjwxCSdpVj2J02wgfJr-E7B1wOUyxYU,80
16
16
  fakesnow/server.py,sha256=8dzaLUUXPzCMm6-ESn0CBws6XSwwOpnUuHQAZJ-4SwU,3011
17
17
  fakesnow/transforms.py,sha256=ellcY5OBc7mqgL9ChNolrqcCLWXF9RH21Jt88FcFl-I,54419
18
18
  fakesnow/types.py,sha256=9Tt83Z7ctc9_v6SYyayXYz4MEI4RZo4zq_uqdj4g3Dk,2681
19
19
  fakesnow/variables.py,sha256=WXyPnkeNwD08gy52yF66CVe2twiYC50tztNfgXV4q1k,3032
20
- fakesnow-0.9.23.dist-info/LICENSE,sha256=kW-7NWIyaRMQiDpryfSmF2DObDZHGR1cJZ39s6B1Svg,11344
21
- fakesnow-0.9.23.dist-info/METADATA,sha256=90vwAf40lg9ipw2urbu9nMq7cEARbtENE0aKd7qSpjo,18064
22
- fakesnow-0.9.23.dist-info/WHEEL,sha256=eOLhNAGa2EW3wWl_TU484h7q1UNgy0JXjjoqKoxAAQc,92
23
- fakesnow-0.9.23.dist-info/entry_points.txt,sha256=2riAUgu928ZIHawtO8EsfrMEJhi-EH-z_Vq7Q44xKPM,47
24
- fakesnow-0.9.23.dist-info/top_level.txt,sha256=500evXI1IFX9so82cizGIEMHAb_dJNPaZvd2H9dcKTA,24
25
- fakesnow-0.9.23.dist-info/RECORD,,
20
+ fakesnow-0.9.24.dist-info/LICENSE,sha256=kW-7NWIyaRMQiDpryfSmF2DObDZHGR1cJZ39s6B1Svg,11344
21
+ fakesnow-0.9.24.dist-info/METADATA,sha256=LHKc6JYn9sxxFh6_i7kqlWz1fmloFv2CCmpalwPVFrE,18064
22
+ fakesnow-0.9.24.dist-info/WHEEL,sha256=eOLhNAGa2EW3wWl_TU484h7q1UNgy0JXjjoqKoxAAQc,92
23
+ fakesnow-0.9.24.dist-info/entry_points.txt,sha256=2riAUgu928ZIHawtO8EsfrMEJhi-EH-z_Vq7Q44xKPM,47
24
+ fakesnow-0.9.24.dist-info/top_level.txt,sha256=500evXI1IFX9so82cizGIEMHAb_dJNPaZvd2H9dcKTA,24
25
+ fakesnow-0.9.24.dist-info/RECORD,,