现在,我已经使用Python中的session.createDataFrame((创建了一个Dataframe。其目的是将此数据帧附加到Snowflake中的现有表对象。
然而,源数据帧的模式与目标表的模式并不完全匹配。在Snowpark Scala中,DataFrameWriter对象的方法option()
将数据帧保存/追加到一个表中,该表允许指定列顺序,因此允许从数据帧中跳过列,因为列可以通过名称匹配。
然而,Snowpark Python目前缺少DataframeWriter的option()
。这迫使Snowflake查找要匹配的架构和列数(在源和目标之间(,否则将引发错误。
不确定Snowpark for Python何时会收到此功能,但在此期间,除了在INSERT查询中对列名进行硬编码外,还有其他选择吗?
你说得对,Snowpark并没有让插入新颖的记录变得容易。但这是可能的。我用Snowpark Java SDK做了这件事,它没有任何源代码/文档,只是把头靠在桌子上,直到它起作用。
我首先对目标表进行了选择(见第一行(,然后获得了模式,然后创建了一个具有正确顺序和类型的新Row对象。使用列";订单;模式而不是列";name";模式它对类型也很挑剔——不喜欢java.util.Dates,但想要时间戳,不喜欢Integers,但需要Longs,等等。
然后做一个";附加"->quot;saveAsTable";。奇迹发生了。同意如果他们接受Map<字符串,对象>插入行或使用名称映射列。但考虑到基于行操作的仓库性能的性质,他们可能想阻止这种做法。
在Java中。。。
DataFrame dfSchema = session.sql("select * from TARGET_TABLE limit 1");
StructType schema = dfSchema.schema();
System.out.println(schema);
Row[] rows = new Row[]{Row.fromArray(new Object[]{endpoint.getDatabaseTable(), statusesArr, numRecords, Integer.valueOf(filenames.size()).longValue(), filenamesArr, urlsArr, startDate, endDate})};
DataFrame df = session.createDataFrame(rows, schema);
System.out.println(df.showString(0, 120));
df.write().mode("Append").saveAsTable("TARGET_TABLE");
在save_as_table方法中,使用参数column_order="名称";。请参阅Snowflake save_as_table文档。这应该按名称匹配列,并允许您省略缺失的列,而不会出现列编号不匹配的错误。
在创建会话时包含模式也是一种很好的做法。请参阅Snowflake create_dataframe文档,了解如何使用StructType类。