tan*_*nia 7 python pandas snowflake-cloud-data-platform
我正在尝试将 Pandas 数据帧中的数据插入 Snowflake 中的表中,但我无法弄清楚如何正确执行此操作。首先,我在 Snowflake 中创建了一个表,其中包含一些类型为 的列VARIANT。例如:
CREATE OR REPLACE TABLE
mydatabase.myschema.results(
DATE date,
PRODUCT string,
PRODUCT_DETAILS variant,
ANALYSIS_META variant,
PRICE float
)
Run Code Online (Sandbox Code Playgroud)
然后在 Pandas 中,我有一个像这样的数据框:
import pandas as pd
record = {'DATE': '2020-11-05',
'PRODUCT': 'blue_banana',
'PRODUCT_DETAILS': "{'is_blue': True, 'is_kiwi': nan}",
'ANALYSIS_META': "None",
'PRICE': 13.02}
df = pd.DataFrame(record, index=[0])
Run Code Online (Sandbox Code Playgroud)
如您所见,我已将列编码VARIANT为字符串,正如我从snowflake-connector文档中了解到的那样,SnowflakeVARIANT类型映射到strPandas 中的 dtype,反之亦然。
所以,到目前为止我所做的尝试如下:
from snowflake.connector import pandas_tools
pandas_tools.write_pandas(
conn=conn,
df=df,
table_name="results",
schema="myschema",
database="mydatabase")
Run Code Online (Sandbox Code Playgroud)
这确实有效,返回
(True,
1,
1,
[('czeau/file0.txt', 'LOADED', 1, 1, 1, 0, None, None, None, None)])
Run Code Online (Sandbox Code Playgroud)
然而,我在 Snowflake 中得到的结果不是正确的VARIANT类型。该字段ANALYSIS_META是正确的NULL,但该字段PRODUCT_DETAILS是类型str。看:

(此外,例如此查询会引发错误:
SELECT * FROM
MYDATABASE.MYSCHEMA.RESULTS
WHERE PRODUCT_DETAILS:is_blue -- should work for json/variant fields
Run Code Online (Sandbox Code Playgroud)
因此,我的问题是:我应该如何正确格式化我的 Pandas 数据框,以便将字段VARIANT作为嵌套字段正确插入雪花表中?我认为将字典转换为字符串可以解决问题,但显然它并没有像我预期的那样工作。我在这里缺少什么?
经过一番调查,我发现以下解决方案可行:
1. 确保列符合 json 标准
这里的关键是json.dumps将您的数据转换为正确的格式(正确的引用、表示null等)。
import pandas as pd
import json
record = {'DATE': '2020-11-05',
'PRODUCT': 'blue_banana',
'PRODUCT_DETAILS': json.dumps({'is_blue': True, 'is_kiwi': None}),
'ANALYSIS_META': json.dumps(None),
'PRICE': 13.02}
df = pd.DataFrame(record, index=[0])
Run Code Online (Sandbox Code Playgroud)
2. 确保你使用parse_json并INSERT迭代
write_pandas我们可以逐行INSERT进入表,确保指定parse_json所需VARIANT类型的列,同时还将值编码为字符串(通过'在其周围放置标记),而不是像最初尝试的那样使用。需要注意的是,如果您有大量数据,此解决方案将会非常慢。
sql = """INSERT INTO MYDATABASE.MYSCHEMA.RESULTS
SELECT
to_date('{DATE}'),
'{PRODUCT}',
parse_json('{PRODUCT_DETAILS}'),
parse_json('{ANALYSIS_META}'),
{PRICE}
"""
### CREATE A SNOWFLAKE CONN...
for i, r in df.iterrows():
conn.cursor().execute(sql.format(**dict(r)))
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5710 次 |
| 最近记录: |