Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Postgresql 尝试插入重复记录后,如果不存在,则使用Slick插入失败_Postgresql_Scala_Insert_Slick - Fatal编程技术网

Postgresql 尝试插入重复记录后,如果不存在,则使用Slick插入失败

Postgresql 尝试插入重复记录后,如果不存在,则使用Slick插入失败,postgresql,scala,insert,slick,Postgresql,Scala,Insert,Slick,我已经使用了来自的解决方案 我使用了公认的答案: 方法 def insertRequiredDocIfNotExists(keys: DocumentInfo) = { val documentMasterId = "hardcoded_value 1" val documentMasterCategory = "hardcoded value 2" val action = { RequiredDocuments.filter(_.required_doc

我已经使用了来自的解决方案

我使用了公认的答案:

方法

def insertRequiredDocIfNotExists(keys: DocumentInfo) = {
    val documentMasterId = "hardcoded_value 1"
    val documentMasterCategory = "hardcoded value 2"

    val action = {
      RequiredDocuments.filter(_.required_document_id__k === keys.documentId)
        .result
        .headOption
        .flatMap{
          case Some(doc) =>
            logger.debug("Required doc already exists")
            DBIO.successful(doc)
          case None =>
            RequiredDocuments.map(rd => (
              rd.doc_master_list__k,
              rd.doc_category__k,
              rd.applicant_id__k,
              rd.application_id__k,
              rd.name,
              rd.required_document_id__k,
              rd.type_k
            )) += (
              Some("Job Application 1"),
              Some("Resume"),
              Some("Job Applicant 1"),
              Some("Lead for Applicant 1"),
              Some("Resume ID 224"),
              Some("Last 6 months WorkExperience Resume"),
              Some("General")
            )
        }
      }.transactionally

      val db = Connections.getSaleForceSchemaDBObject().db
      db.run(action)
    }
用法

Await.result(insertRequiredDocIfNotExists(keys), Duration.Inf)
// inserts into other tables.
日志

错误消息如下所示:

ERROR: duplicate key value violates unique constraint "hcu_idx_required_document__c_required_document_uuid__c"
Detail: Key (required_document_id__k)=(c63386c0-d599-4d47-a535-941a24a07a6e) already exists.: org.postgresql.util.PSQLException
org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "required_document_id__k"
Detail: Key (required_document_uuid__c)=(c63386c0-d599-4d47-a535-941a24a07a6e) already exists.
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2433)
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2178)
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:306)
at org.postgresql.jdbc.PgStatement.executeInternal(PgStatement.java:441)
at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:365)
at org.postgresql.jdbc.PgPreparedStatement.executeWithFlags(PgPreparedStatement.java:155)
at org.postgresql.jdbc.PgPreparedStatement.executeUpdate(PgPreparedStatement.java:132)
at slick.jdbc.LoggingPreparedStatement.$anonfun$executeUpdate$5(LoggingStatement.scala:155)
at scala.runtime.java8.JFunction0$mcI$sp.apply(JFunction0$mcI$sp.java:12)
at slick.jdbc.LoggingStatement.logged(LoggingStatement.scala:84)
at slick.jdbc.LoggingPreparedStatement.executeUpdate(LoggingStatement.scala:155)
at slick.jdbc.JdbcActionComponent$InsertActionComposerImpl$SingleInsertAction.$anonfun$run$11(JdbcActionComponent.scala:510)
at slick.jdbc.JdbcBackend$SessionDef.withPreparedStatement(JdbcBackend.scala:386)
at slick.jdbc.JdbcBackend$SessionDef.withPreparedStatement$(JdbcBackend.scala:381)
at slick.jdbc.JdbcBackend$BaseSession.withPreparedStatement(JdbcBackend.scala:448)
at slick.jdbc.JdbcActionComponent$InsertActionComposerImpl.preparedInsert(JdbcActionComponent.scala:501)
at slick.jdbc.JdbcActionComponent$InsertActionComposerImpl$SingleInsertAction.run(JdbcActionComponent.scala:507)
at slick.jdbc.JdbcActionComponent$SimpleJdbcProfileAction.run(JdbcActionComponent.scala:30)
at slick.jdbc.JdbcActionComponent$SimpleJdbcProfileAction.run(JdbcActionComponent.scala:27)
at slick.basic.BasicBackend$DatabaseDef$$anon$2.liftedTree1$1(BasicBackend.scala:275)
at slick.basic.BasicBackend$DatabaseDef$$anon$2.run(BasicBackend.scala:275)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)


Slick有一个
upsert
方法,可以在项目存在时更新该项目。我不想使用
upsert
,因为每个周期更新同一项多达20次是没有意义的。

好的,这个问题的一个可能解决方案是在事务的两端查询要检查的存在值,然后插入。。。考虑到DBIOAction是一个monad,您可以编写类似以下内容的解决方案:

val query = RequiredDocuments.filter(_.required_document_id__k === keys.documentId)

val newRecord = {
  (
    Some("Job Application 1"),
    Some("Resume"),
    Some("Job Applicant 1"),
    Some("Lead for Applicant 1"),
    Some("Resume ID 224"),
    Some("Last 6 months WorkExperience Resume"),
    Some("General")
  )
}

val finalQuery = {
  query.exists.result.flatMap{ exitingRecord =>
    if (!exitingRecord) {
      RequiredDocuments.map{rd => (
        rd.doc_master_list__k,
        rd.doc_category__k,
        rd.applicant_id__k,
        rd.application_id__k,
        rd.name,
        rd.required_document_id__k,
        rd.type_k
      )} += newRecord
    } else {
      DBIO.successful(None)
    }
  }
}
db.run(finalQuery.transactionally)

希望对您有所帮助:)

您可以使用
插入。。。关于冲突
@a_horse_和_no_name你能提供一个例子说明我如何做到这一点吗。@a_horse_和_no_name,slick不支持
插入冲突
,请参阅混淆层的“乐趣”。。。。但这是唯一可扩展且正确的方法。你应该想办法。它支持“本地查询”或类似的东西吗?ORM非常讨厌@a_horse_和_no_名字,这是我必须处理的。。。