pandas Snowflake write_panda无法正确插入日期

piztneat  于 2023-01-07  发布在  其他
关注(0)|答案(3)|浏览(126)

我有一个名为“df”的panda数据框,是我用Netezza数据库的SQL查询结果创建的,我在Jupyter notebook中工作,这个数据框有两行和两列(CREATEDDATE和STAGEDATE)包含日期时间值,当我运行print(df)时,结果如下:

ID ISDELETED            PARENTID         CREATEDBYID  \
0  017o000003tQRftAAG     false  a0no000000Hrv1IAAR  005o0000001w8wgAAA   
1  017o000003jl52cAAA     false  a0no000000GszDUAAZ  005o0000001w2pTAAQ   

          CREATEDDATE    FIELD OLDVALUE NEWVALUE  STAGEDATE  
0 2015-07-30 14:51:41  created     None     None 2016-06-06  
1 2015-07-16 14:48:37  created     None     None 2016-06-06

如果我运行print(df.dtypes),结果如下:

ID                     object
ISDELETED              object
PARENTID               object
CREATEDBYID            object
CREATEDDATE    datetime64[ns]
FIELD                  object
OLDVALUE               object
NEWVALUE               object
STAGEDATE      datetime64[ns]
dtype: object

因此,据我所知,我的datetime列的格式是正确的,可以使用write_panda()写入Snowflake,但是,在我这样做之后,Snowflake中的日期就大不相同了:

例如,2016-06-06的STAGEDATE值现在是48399-06-06。有人知道如何修复这个问题吗?我正在使用pyodbc从Netezza进行拉取,并使用df = cs.execute()填充 Dataframe 。我正在导入并使用snowflake.connector连接到Snowflake,并运行以下命令来获取write_panda:

from snowflake.connector.pandas_tools import write_pandas
axr492tv

axr492tv1#

我用pday写的代码找到了一个解决方案,这个函数自动给日期类型cols添加一个时区(函数中默认的是UTC)。

def fix_date_cols(df, tz='UTC'):
    cols = df.select_dtypes(include=['datetime64[ns]']).columns
    for col in cols:
        df[col] = df[col].dt.tz_localize(tz)

因此,我建议在将 Dataframe 传递给write_pandas之前使用此函数。
从我得到的问题是,datetime对象被误解了,因为它定义得不够好。添加时区信息将强制将元素解释为datetime。
但我真的建议你阅读this惊人的对话,其中有很好的解释,它真的帮助了我。

hec6srdp

hec6srdp2#

SELECT '2016-06-06'::timestamp as a
    ,to_timestamp_ntz(date_part('epoch_second', a),0)::date as a_s
    ,to_timestamp_ntz(date_part('epoch_millisecond', a),0)::date as a_ms
    ,to_timestamp_ntz(date_part('epoch_millisecond', a),3)::date as b_ms;

给予

A                        A_S          A_MS         B_MS
2016-06-06 00:00:00.000  2016-06-06   48399-06-06  2016-06-06

也就是说,你的日期,变成纪元毫秒和解析为秒给你的日期。
因此,您要么扔掉毫秒,要么改变日期的解析方式。

hmae6n7t

hmae6n7t3#

@Lorenzo Vitali的解决方案很好用,我已经把它添加到我的snowflake助手类中,你需要记住返回df。

def fix_date_cols(df, tz='UTC'):
cols = df.select_dtypes(include=['datetime64[ns]']).columns
for col in cols:
    df[col] = df[col].dt.tz_localize(tz)
return df

相关问题