【问题标题】:Concatenating databases with Squeryl使用 Squeryl 连接数据库
【发布时间】:2011-12-29 08:01:21
【问题描述】:

我正在尝试使用 Squeryl 从一个数据库中获取表的内容,并将其附加到另一个数据库中的等效表中。在此过程中必须重新分配主键,但我收到错误 NULL not allowed for column "SIMID"。这是为什么呢?

object Concatenator {
  def main(args: Array[String]) {
    Class.forName("org.h2.Driver");

    val seshA = Session.create(
      java.sql.DriverManager.getConnection("jdbc:h2:file:data/resultsA", "sa", "password"),
      new H2Adapter
    )

    val seshB = Session.create(
      java.sql.DriverManager.getConnection("jdbc:h2:file:data/resultsB", "sa", "password"),
      new H2Adapter
    )

    using(seshA){
      import Library._
      from(sims){s => select(s)}.foreach{item =>
        using(seshB){
          sims.insert(item);
        }
      }
    }

  }

  case class Simulation(
    @Column("SIMID")
    var id: Long, 
    val date: Date
  ) extends KeyedEntity[Long]

  object Library extends Schema {
    val sims = table[Simulation]

    on(sims)(s => declare(
      s.id is(unique, indexed, autoIncremented)
    ))
  }
}

更新: 我认为这可能与数据库有关。它们是使用 JPA/EclipseLink 在 Java 项目中创建的,除了为我的实体生成表之外,它还创建了一个名为 SEQUENCE 的表,大概用于生成主键。

我发现我可以在 Squeryl 中创建一个全新的表并手动将两个数据库的内容放入其中,从而达到相同的效果。有趣的是,这个新表没有自动生成任何 SEQUENCE 表。所以我猜这归结为 JPA/EclipseLink 是如何生成我的主键的?

更新 2: 根据要求,我将 trace_level_file=3 附加到 url,文件在这里:resultsA.trace.dbresultsB.trace.db。 B是我认为更有趣的一个。此外,我还添加了数据库here 的简化版本,其中删除了不必要的表(相同的数据库用于结果A 和结果B)。

【问题讨论】:

  • 您使用的是什么版本的 Squeryl?您愿意将可重现的测试用例发布到 github 以便我看一下吗?
  • 我有几天没上班,所以不能马上发布一个空白测试数据库,但我在上面添加了一个更新,希望能提供一些线索。谢谢
  • 能否将;trace_level_file=3 附加到数据库URL,然后检查或上传.trace.db 文件?它应该包含导致问题的所有 JDBC 方法调用。

标签: scala h2 squeryl


【解决方案1】:

只是有时间更仔细地研究一下。我发现你是在正确的轨道上。虽然我猜 EclipseLink 使用序列来生成 PK 值,但 Squeryl 将列定义为:

simid bigint 非空主键 auto_increment

如果没有 auto_increment 标志,则永远不会在列中放置一个值,并且您最终会遇到您提到的约束违规。听起来您已经解决了这个问题,但希望这会对您或将来的其他人有所帮助。

【讨论】:

    【解决方案2】:

    不是真正的解决方案,但我的解决方法是创建一个新数据库

    val seshNew = Session.create(java.sql.DriverManager.getConnection("jdbc:h2:file:data/resultsNew", "sa","password"),new H2Adapter)
    

    然后将其他数据库中的所有数据写入其中

    using(seshNew){
        sims.insert(new Simulation(0,item.date))
    }
    

    主键 0 被适当覆盖。

    【讨论】:

      猜你喜欢
      • 2012-10-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多