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 +0 -28
- fakesnow/cursor.py +2 -0
- fakesnow/pandas_tools.py +33 -2
- {fakesnow-0.9.23.dist-info → fakesnow-0.9.24.dist-info}/METADATA +1 -1
- {fakesnow-0.9.23.dist-info → fakesnow-0.9.24.dist-info}/RECORD +9 -9
- {fakesnow-0.9.23.dist-info → fakesnow-0.9.24.dist-info}/LICENSE +0 -0
- {fakesnow-0.9.23.dist-info → fakesnow-0.9.24.dist-info}/WHEEL +0 -0
- {fakesnow-0.9.23.dist-info → fakesnow-0.9.24.dist-info}/entry_points.txt +0 -0
- {fakesnow-0.9.23.dist-info → fakesnow-0.9.24.dist-info}/top_level.txt +0 -0
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.
|
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]
|
@@ -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=
|
7
|
-
fakesnow/cursor.py,sha256=
|
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=
|
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.
|
21
|
-
fakesnow-0.9.
|
22
|
-
fakesnow-0.9.
|
23
|
-
fakesnow-0.9.
|
24
|
-
fakesnow-0.9.
|
25
|
-
fakesnow-0.9.
|
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,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|