fakesnow 0.9.42__py3-none-any.whl → 0.9.43__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/cursor.py +1 -2
- fakesnow/expr.py +11 -0
- fakesnow/server.py +9 -3
- fakesnow/transforms/stage.py +1 -11
- {fakesnow-0.9.42.dist-info → fakesnow-0.9.43.dist-info}/METADATA +5 -4
- {fakesnow-0.9.42.dist-info → fakesnow-0.9.43.dist-info}/RECORD +10 -10
- {fakesnow-0.9.42.dist-info → fakesnow-0.9.43.dist-info}/WHEEL +0 -0
- {fakesnow-0.9.42.dist-info → fakesnow-0.9.43.dist-info}/entry_points.txt +0 -0
- {fakesnow-0.9.42.dist-info → fakesnow-0.9.43.dist-info}/licenses/LICENSE +0 -0
- {fakesnow-0.9.42.dist-info → fakesnow-0.9.43.dist-info}/top_level.txt +0 -0
fakesnow/cursor.py
CHANGED
@@ -10,7 +10,6 @@ from types import TracebackType
|
|
10
10
|
from typing import TYPE_CHECKING, Any, cast
|
11
11
|
|
12
12
|
import duckdb
|
13
|
-
import pandas as pd
|
14
13
|
import pyarrow # needed by fetch_arrow_table()
|
15
14
|
import snowflake.connector.converter
|
16
15
|
import snowflake.connector.errors
|
@@ -194,7 +193,7 @@ class FakeSnowflakeCursor:
|
|
194
193
|
|
195
194
|
def _put_files(self, put_stage_data: stage.UploadCommandDict) -> None:
|
196
195
|
results = stage.upload_files(put_stage_data)
|
197
|
-
_df =
|
196
|
+
_df = pyarrow.Table.from_pylist(results)
|
198
197
|
self._duck_conn.execute("select * from _df")
|
199
198
|
self._arrow_table = self._duck_conn.fetch_arrow_table()
|
200
199
|
self._rowcount = self._arrow_table.num_rows
|
fakesnow/expr.py
CHANGED
@@ -30,3 +30,14 @@ def key_command(expression: exp.Expression) -> str:
|
|
30
30
|
key = expression.key.upper()
|
31
31
|
|
32
32
|
return key
|
33
|
+
|
34
|
+
|
35
|
+
def normalise_ident(name: str) -> str:
|
36
|
+
"""
|
37
|
+
Strip double quotes if present else return uppercased.
|
38
|
+
Snowflake treats quoted identifiers as case-sensitive and un-quoted identifiers as case-insensitive
|
39
|
+
"""
|
40
|
+
if name.startswith('"') and name.endswith('"'):
|
41
|
+
return name[1:-1] # Strip quotes
|
42
|
+
|
43
|
+
return name.upper()
|
fakesnow/server.py
CHANGED
@@ -18,6 +18,7 @@ from starlette.routing import Route
|
|
18
18
|
|
19
19
|
from fakesnow.arrow import to_ipc, to_sf
|
20
20
|
from fakesnow.converter import from_binding
|
21
|
+
from fakesnow.expr import normalise_ident
|
21
22
|
from fakesnow.fakes import FakeSnowflakeConnection
|
22
23
|
from fakesnow.instance import FakeSnow
|
23
24
|
from fakesnow.rowtype import describe_as_rowtype
|
@@ -39,8 +40,8 @@ class ServerError(Exception):
|
|
39
40
|
|
40
41
|
|
41
42
|
async def login_request(request: Request) -> JSONResponse:
|
42
|
-
database = request.query_params.get("databaseName")
|
43
|
-
schema = request.query_params.get("schemaName")
|
43
|
+
database = (d := request.query_params.get("databaseName")) and normalise_ident(d)
|
44
|
+
schema = (s := request.query_params.get("schemaName")) and normalise_ident(s)
|
44
45
|
body = await request.body()
|
45
46
|
if request.headers.get("Content-Encoding") == "gzip":
|
46
47
|
body = gzip.decompress(body)
|
@@ -64,7 +65,10 @@ async def login_request(request: Request) -> JSONResponse:
|
|
64
65
|
{"name": "AUTOCOMMIT", "value": True},
|
65
66
|
{"name": "CLIENT_SESSION_KEEP_ALIVE_HEARTBEAT_FREQUENCY", "value": 3600},
|
66
67
|
],
|
67
|
-
"sessionInfo": {
|
68
|
+
"sessionInfo": {
|
69
|
+
"databaseName": database,
|
70
|
+
"schemaName": schema,
|
71
|
+
},
|
68
72
|
},
|
69
73
|
"success": True,
|
70
74
|
}
|
@@ -147,6 +151,8 @@ async def query_request(request: Request) -> JSONResponse:
|
|
147
151
|
"total": cur._rowcount, # noqa: SLF001
|
148
152
|
"queryId": cur.sfqid,
|
149
153
|
"queryResultFormat": "arrow",
|
154
|
+
"finalDatabaseName": conn.database,
|
155
|
+
"finalSchemaName": conn.schema,
|
150
156
|
},
|
151
157
|
"success": True,
|
152
158
|
}
|
fakesnow/transforms/stage.py
CHANGED
@@ -13,6 +13,7 @@ import sqlglot
|
|
13
13
|
from snowflake.connector.file_util import SnowflakeFileUtil
|
14
14
|
from sqlglot import exp
|
15
15
|
|
16
|
+
from fakesnow.expr import normalise_ident
|
16
17
|
from fakesnow.params import MutableParams
|
17
18
|
|
18
19
|
# TODO: clean up temp files on exit
|
@@ -198,17 +199,6 @@ def put_stage(
|
|
198
199
|
return transformed
|
199
200
|
|
200
201
|
|
201
|
-
def normalise_ident(name: str) -> str:
|
202
|
-
"""
|
203
|
-
Strip double quotes if present else return uppercased.
|
204
|
-
Snowflake treats quoted identifiers as case-sensitive and un-quoted identifiers as case-insensitive
|
205
|
-
"""
|
206
|
-
if name.startswith('"') and name.endswith('"'):
|
207
|
-
return name[1:-1] # Strip quotes
|
208
|
-
|
209
|
-
return name.upper()
|
210
|
-
|
211
|
-
|
212
202
|
def parts_from_var(var: str, current_database: str | None, current_schema: str | None) -> tuple[str, str, str]:
|
213
203
|
parts = var.split(".")
|
214
204
|
if len(parts) == 3:
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: fakesnow
|
3
|
-
Version: 0.9.
|
3
|
+
Version: 0.9.43
|
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
|
@@ -420,7 +420,7 @@ Fully supported:
|
|
420
420
|
- Multiple databases
|
421
421
|
- [Parameter binding](https://docs.snowflake.com/en/user-guide/python-connector-example#binding-data) in queries
|
422
422
|
- Table comments
|
423
|
-
- Pandas integration including [write_pandas(..)](https://docs.snowflake.com/en/user-guide/python-connector-api#write_pandas)
|
423
|
+
- Pandas integration including [write_pandas(..)](https://docs.snowflake.com/en/user-guide/python-connector-api#write_pandas)
|
424
424
|
- Result batch retrieval via [get_result_batches()](https://docs.snowflake.com/en/user-guide/python-connector-api#get_result_batches)
|
425
425
|
- HTTP server for non-Python connectors
|
426
426
|
|
@@ -431,7 +431,8 @@ Partially supported:
|
|
431
431
|
- Semi-structured data operations
|
432
432
|
- Tags
|
433
433
|
- User management
|
434
|
-
-
|
434
|
+
- Stages and PUT
|
435
|
+
- `COPY INTO` from S3 sources and stages, see [COPY INTO](#copy-into)
|
435
436
|
|
436
437
|
Not yet implemented:
|
437
438
|
|
@@ -447,7 +448,7 @@ For more detail see the [test suite](tests/).
|
|
447
448
|
|
448
449
|
## COPY INTO
|
449
450
|
|
450
|
-
`COPY INTO` can be used from S3 sources. By default the standard AWS credential chain will be used. If you are getting an HTTP 403 or need to provide alternative S3 credentials you can use the duckdb [CREATE SECRET](https://duckdb.org/docs/stable/extensions/httpfs/s3api) statement. For an example of creating a secret to use a moto S3 endpoint see `s3_client` in [conftest.py](tests/conftest.py#L80)
|
451
|
+
`COPY INTO` can be used from S3 sources and stages. By default the standard AWS credential chain will be used. If you are getting an HTTP 403 or need to provide alternative S3 credentials you can use the duckdb [CREATE SECRET](https://duckdb.org/docs/stable/extensions/httpfs/s3api) statement. For an example of creating a secret to use a moto S3 endpoint see `s3_client` in [conftest.py](tests/conftest.py#L80)
|
451
452
|
|
452
453
|
## Contributing
|
453
454
|
|
@@ -6,8 +6,8 @@ fakesnow/cli.py,sha256=9qfI-Ssr6mo8UmIlXkUAOz2z2YPBgDsrEVaZv9FjGFs,2201
|
|
6
6
|
fakesnow/conn.py,sha256=diCwcjaCBrlCn9PyjbScfIQTNQjqiPTkQanUTqcvblE,6009
|
7
7
|
fakesnow/converter.py,sha256=wPOfsFXIUJNJSx5oFNAxh13udxmAVIIHsLK8BiGkXGA,1635
|
8
8
|
fakesnow/copy_into.py,sha256=utlV03RWHdWblIlKs92Q__9BWHi_gvqT76RV6tEMWTo,16006
|
9
|
-
fakesnow/cursor.py,sha256=
|
10
|
-
fakesnow/expr.py,sha256=
|
9
|
+
fakesnow/cursor.py,sha256=A1jWLGkXzHcYbM0wFrbh2PiewzFFS7ZlfOm-x3AGHgg,25412
|
10
|
+
fakesnow/expr.py,sha256=tLcHC-mx2O6-vCt77RVlRQa3CovqUdu4vc5WOSmuQdk,1231
|
11
11
|
fakesnow/fakes.py,sha256=JQTiUkkwPeQrJ8FDWhPFPK6pGwd_aR2oiOrNzCWznlM,187
|
12
12
|
fakesnow/fixtures.py,sha256=2rj0MTZlaZc4PNWhaqC5IiiLa7E9G0QZT3g45YawsL0,633
|
13
13
|
fakesnow/info_schema.py,sha256=lqEYD5aWK2MamjALbj6ct7pz_1yyAq3tAk51kLa8NKk,9872
|
@@ -18,17 +18,17 @@ fakesnow/pandas_tools.py,sha256=wI203UQHC8JvDzxE_VjE1NeV4rThek2P-u52oTg2foo,3481
|
|
18
18
|
fakesnow/params.py,sha256=Hp7tBiDycdOh8LuRoISsOZycD7DufDAMKyF_hqEjh6M,929
|
19
19
|
fakesnow/py.typed,sha256=B-DLSjYBi7pkKjwxCSdpVj2J02wgfJr-E7B1wOUyxYU,80
|
20
20
|
fakesnow/rowtype.py,sha256=QUp8EaXD5LT0Xv8BXk5ze4WseEn52xoJ6R05pJjs5mM,2729
|
21
|
-
fakesnow/server.py,sha256=
|
21
|
+
fakesnow/server.py,sha256=NzhpVM_3L9QeG84bhn0_It6ABM9ifs1CYWPgKhWaOeE,7511
|
22
22
|
fakesnow/variables.py,sha256=BGnD4LAdVByfJ2GXL6qpGBaTF8ZJRjt3pdJsd9sIAcw,3134
|
23
23
|
fakesnow/transforms/__init__.py,sha256=3dpcXjeLkfc4e9rO0G8Mnv9zZgmwsKSwQ7UJeyLYnOg,2837
|
24
24
|
fakesnow/transforms/merge.py,sha256=H2yYyzGsxjpggS6PY91rAUtYCFuOkBm8uGi0EO0r6T0,8375
|
25
25
|
fakesnow/transforms/show.py,sha256=NIJDkf4-ns4VTw0DQphEn2DnwxQjXyTU2wS9VSUh6Wc,19919
|
26
|
-
fakesnow/transforms/stage.py,sha256=
|
26
|
+
fakesnow/transforms/stage.py,sha256=VRE122Twha1Dd7QC2rdAAWWG93OxIiJZv2DfvGSsMZ8,10047
|
27
27
|
fakesnow/transforms/transforms.py,sha256=ykzay7J28MsifhRKhm5qJJd__hMcLNVZTT14MSdWcJs,49102
|
28
|
-
fakesnow-0.9.
|
28
|
+
fakesnow-0.9.43.dist-info/licenses/LICENSE,sha256=kW-7NWIyaRMQiDpryfSmF2DObDZHGR1cJZ39s6B1Svg,11344
|
29
29
|
tools/decode.py,sha256=kC5kUvLQxdCkMRsnH6BqCajlKxKeN77w6rwCKsY6gqU,1781
|
30
|
-
fakesnow-0.9.
|
31
|
-
fakesnow-0.9.
|
32
|
-
fakesnow-0.9.
|
33
|
-
fakesnow-0.9.
|
34
|
-
fakesnow-0.9.
|
30
|
+
fakesnow-0.9.43.dist-info/METADATA,sha256=tUAcWIfezqI1Lu64-sz8VToB4bFIyfaEFyOPCJpDREY,20684
|
31
|
+
fakesnow-0.9.43.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
32
|
+
fakesnow-0.9.43.dist-info/entry_points.txt,sha256=2riAUgu928ZIHawtO8EsfrMEJhi-EH-z_Vq7Q44xKPM,47
|
33
|
+
fakesnow-0.9.43.dist-info/top_level.txt,sha256=Yos7YveA3f03xVYuURqnBsfMV2DePXfu_yGcsj3pPzI,30
|
34
|
+
fakesnow-0.9.43.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|