[英]Spark DataFame : JDBC Write Auto generated fields
我有 dataframe 與表完全匹配,除了自動生成的主鍵。
下面是我的表
ID |FirstName |LastName |CreOn |CreBy
auto-generated |Varchar(20)|Varchar(20)| timestamp| Varchar(20)
下面是我的 dataframe
FirstName|LastName|CreOn |CreBy
String |String |timestamp| String
當我使用帶有“附加”模式的 spark.jdb.write 時,出現以下錯誤
架構 abc Position 14 的權限被拒絕
我們如何處理自動生成的字段。
與 Pyspark 相比,我是否應該更喜歡使用 Python 來執行 JDBC 操作,因為我將更好地控制批量大小和回滾
這取決於您的數據大小....如果行數很大,python 很可能會失敗,您將無法加載數據。
一種可能的方法是使用臨時表。 將數據從 spark 加載到臨時表。 然后使用 python 庫運行查詢以將數據從登台移動到主表。
至於批量大小,您也可以在 spark jdbc 中配置它。
對於非常大的數據,我建議使用 SQOOP 移動數據,因為 spark 無法與 db 形成並發連接,而 sqoop 可以建立多個映射器來將數據寫入數據庫。
當 dataframe 保存到 SQL 數據庫中時,Spark 將僅寫入數據庫中存在於 dataframe 中的那些列。 因此,如果ID
列不是 dataframe 的一部分,Spark 將在插入操作期間忽略它。
insert 語句在JdbcUtils.getInsertStatement()中創建,這里只有作為底層 rdd 一部分的列包含在 create 語句中:
val columns =
[...]
rddSchema.fields.map { col =>
val normalizedName = tableColumnNames.find(f => columnNameEquality(f, col.name)).getOrElse {
throw new AnalysisException(s"""Column "${col.name}" not found in schema $tableSchema""")
}
dialect.quoteIdentifier(normalizedName)
}.mkString(",")
[...]
s"INSERT INTO $table ($columns) VALUES ($placeholders)"
例如給定表定義
create table address (
id serial,
FirstName varchar(20),
LastName varchar(20),
CreOn timestamp,
CreBy varchar(20),
constraint pk primary key (id))
和 Python 代碼
df = spark.createDataFrame(
[("John", "Doe", "1970-01-02 03:46:40", "py2")],
['FirstName','LastName','CreOn','CreBy']
)
df.write.mode("append").jdbc(<jdbc url>, "address", \
properties={"driver":...,"user": ..., "password": ...})
Spark 創建插入語句
INSERT INTO address ("firstname","lastname","creon","creby") VALUES (?,?,?,?)
並且插入操作成功。
所以自動生成的字段不應該是 dataframe 的一部分,並且錯誤Permission denied
可能與自動生成的字段無關。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.