如何使用pyspark将数据写入Azure Sql数据库?

问题描述 投票:0回答:1

我已使用以下代码将数据写入 Azure sql 数据库:

def write_to_sqldatabase(final_table, target_table):
    #Write table data into a spark dataframe
    final_table.write.format("jdbc") \
        .option("url", f"jdbc:sqlserver://{SERVER};databaseName={DATABASE}") \
        .option("dbtable", f'....{target_table}') \
        .option("user", USERNAME) \
        .option("password", PASSWORD) \
        .mode("append") \
        .save()

这不再起作用了。我现在收到以下错误:

Py4JJavaError:调用 o11913.save 时发生错误。 : org.apache.spark.SparkException:作业由于阶段失败而中止: 阶段 63.0 中的任务 2 失败了 4 次,最近一次失败:丢失任务 2.3 在阶段 63.0 (TID 322) (vm-32517978 执行程序 1): java.sql.BatchUpdateException: 违反 PRIMARY KEY 约束 'PK_tblSFDC_Account'。无法在对象中插入重复的键 '.....桌子'。重复的键值为 (0xxxxxx)。

之前我也遇到过这个问题,但是通过截断sql数据库中的表来修复它。

现在我尝试做同样的事情,但我保留了违规的错误。

这是怎么发生的?

pyspark azure-sql-database
1个回答
0
投票
Violation of PRIMARY KEY constraint 'PK_tblSFDC_Account'. Cannot insert duplicate key in object '.....table'. The duplicate key value is (0xxxxxx).
  • 您看到的错误消息表明您的 SQL Server 数据库中的主键约束存在问题。该约束用于确保表中的每一行都是唯一的,并且可以通过唯一键来标识。该错误消息表明违反了此约束,这意味着表中存在重复行或具有非唯一键的行。您可能需要检查数据并确保每一行都有唯一的键值。

我同意@ThomA当您在尝试将数据插入空表时遇到此错误时,这意味着您尝试添加的信息在指定为主键的列中具有多个具有相同值的行。 主键确保每一行都是不同的并且可以通过唯一键进行识别。 由于您的表最初是空的,因此错误表明您尝试插入的数据与此唯一性要求相矛盾。 您的数据中似乎存在具有重复键值的行。

我正在 INSERTING 到 SQL 数据库中的空表中: enter image description here 样本数据:

data = [(1, "Movie 1"), (2, "Movie 2"), (1, "Duplicate Movie")]
columns = ["movie_id", "title"]

(1, "Duplicate Movie") 是具有相同 PK 的重复记录。

final_table = final_table.dropDuplicates(["movie_id"])
target_table = "movies"
final_table.write.format("jdbc") \
    .option("url", jdbcUrl) \
    .option("dbtable", target_table) \
    .option("user", connectionProperties["user"]) \
    .option("password", connectionProperties["password"]) \
    .mode("append") \
    .save()

final_table = Final_table.dropDuplicates(["movie_id"])

如果数据框中出现任何重复项,此过程可确保将其删除。

结果: enter image description here

在 SQL 中,您还可以 (CTE) 删除重复行:

WITH CTE AS (
    SELECT 
        movie_id,
        title,
        ROW_NUMBER() OVER (PARTITION BY movie_id ORDER BY (SELECT NULL)) AS RowNum
    FROM [dbo].[movies]
)
DELETE FROM CTE WHERE RowNum > 1;
© www.soinside.com 2019 - 2024. All rights reserved.