【问题标题】:Error Cannot insert duplicate key row in object while loading data into Azure SQL DB from Azure Databricks将数据从 Azure Databricks 加载到 Azure SQL DB 时出现错误,无法在对象中插入重复的键行
【发布时间】:2020-08-14 17:20:16
【问题描述】:

我正在使用以下简单的代码行将数据从 Azure Databricks 加载到 SQL DB

val loadsqldb = spark.sql("""SELECT * FROM TABLEA""")
// WRITE FROM CONFIG
val writeConfig = Config(Map(
  "url"          -> url,
  "databaseName" -> databaseName,
  "dbTable"      -> "dbo.TABLENAME",
  "user"         -> user,
  "password"     -> password,
  "connectTimeout" -> "5"
))

//~
loadsqldb.write.mode(SaveMode.Overwrite).option("truncate", true).sqlDB(writeConfig)

我们的服务器上有一个唯一的 ID 密钥,我们必须保留它,如下所示:

CREATE UNIQUE INDEX i__NeighbourhoodCategoryHourlyForecast_unique
ON almanac_devdb.dbo.NeighbourhoodCategoryHourlyForecast (fk_neighbourhoods, fk_categories, local_date, local_hour)
GO

当我尝试将数据加载到我们的 SQL 数据库时,我们收到以下错误;

Cannot insert duplicate key row in object 'dbo.TABLENAME' with unique index 'i__TABLENAME_unique'. The duplicate key value is (36983, 130000, 2020-08-12, 14).

有人建议我找到某种方法让 Databricks 合并到 OVERWRITE,但我不确定如何执行此操作,或者即使这样做是否正确?

【问题讨论】:

    标签: sql-server apache-spark azure-databricks


    【解决方案1】:

    我建议按照以下步骤操作(不要在 spark 端更改任何内容,而是在 sql server 端执行以下步骤)-

    1. Create view 位于 target_table 之上,您想在其中写入 spark 数据帧数据
    2. 创建INSTEAD OF INSERT Trigger,使所有插入命令都应通过步骤#1 中创建的视图进行
    CREATE TRIGGER <trigger_name> 
    ON <view_created_in_step_1>
    INSTEAD OF INSERT
    AS
    BEGIN
        Merge statment...
       
    END
    
    1. Merge 语句用于插入和更新单语句。 Follow this tutorial.

    如果键(不)匹配,您可能还想查看this tutorial 以获取与事务相关的查询以更新或插入表

    【讨论】:

    • 感谢您与我们联系。但是,我不明白您的建议是否可以通过在 SQL Server 上进行更改来实现?这是因为我从数据块加载数据。确定需要在 Databricks 上进行更改吗?
    • 弹出的错误与一些主要的bkey/unique约束有关。这是因为当你说df.write. 时,默认情况下spark 会尝试在提到的目标表上调用insert 语句。要覆盖该盲插入语句,有一种称为insted of insert 触发器的机制,您可以在其中提及自己的活动(例如在调用插入时使用 upsert)
    • 感谢您再次与我们联系。因此,我将尝试在我的 SQL Server 上进行更改。如果您有任何其他示例,将不胜感激。如果没有,我将尝试使用您提供的示例
    • 您在 Merge 语句教程中提到的链接没有任何有关合并数据的信息
    • 我也看了下面的例子tutorialgateway.org/instead-of-insert-triggers-in-sql-server。真的有必要创建临时表吗?
    【解决方案2】:

    删除唯一索引键的重复项。

    df.dropDuplicates(Array("col1","col2"))
    

    在此之后,尝试写入您的数据库。

    【讨论】:

    • 你不能用这个。考虑一个场景,您在数据框中没有重复项,但您尝试插入的密钥已经存在于数据库中。
    • @Someshwar,您说“在数据框中没有重复项”是正确的,但是我仍然不确定在 SQL Server 上进行更改将如何解决这个问题?
    • INSTEAD OF TRIGGERS 将帮助您覆盖默认插入。基本上,如果密钥不可用,我们想在这里插入,如果可用则更新。您可能想在这里获得更多信息-sqlservertutorial.net/sql-server-triggers/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-22
    相关资源
    最近更新 更多