使用scala slick从.csv文件填充H2内存数据库

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

上下文

  • 给出以下Slick数据库模式
class Suppliers(tag: Tag)
  extends Table[(Int, String, String, String, String, String)](tag, "SUPPLIERS") {

  // This is the primary key column:
  def id: Rep[Int] = column[Int]("SUP_ID", O.PrimaryKey)
  def name: Rep[String] = column[String]("SUP_NAME")
  def street: Rep[String] = column[String]("STREET")
  def city: Rep[String] = column[String]("CITY")
  def state: Rep[String] = column[String]("STATE")
  def zip: Rep[String] = column[String]("ZIP")

  // Every table needs a * projection with the same type as the table's type parameter
  def * : ProvenShape[(Int, String, String, String, String, String)] =
    (id, name, street, city, state, zip)
}
  • 以下.csv示例文件
101, "Acme, Inc.", "99 Market Street", "Groundsville", "CA", "95199"
49, "Superior Coffee", "1 Party Place", "Mendocino", "CA", "95460"
150, "The High Ground", "100 Coffee Lane", "Meadows", "CA", "93966"
  • [When我设置并尝试加载.csv文件(其路径作为系统属性被接收
object HelloSlick extends App {

  val csvPath = System.getProperty("csvPath")

  val db = Database.forConfig("h2mem")
  try {

    val suppliers = TableQuery[Suppliers]

    val setup: DBIO[Unit] = DBIO.seq(
      suppliers.schema.create,
      sqlu"INSERT INTO SUPPLIERS SELECT * FROM CSVREAD('$csvPath')"
    )

    val resultFuture = db.run(setup)

    Await.result(resultFuture, Duration.Inf)

  } finally db.close
}
  • 然后创建数据库并成功加载.csv数据

但是...

实际上正在发生的是:

Exception in thread "main" org.h2.jdbc.JdbcSQLNonTransientException: IO Exception: "IOException reading ?"; SQL statement:
INSERT INTO SUPPLIERS SELECT * FROM CSVREAD('?') [90028-199]
    at org.h2.message.DbException.getJdbcSQLException(DbException.java:502)
    at org.h2.message.DbException.getJdbcSQLException(DbException.java:427)
    at org.h2.tools.Csv.convertException(Csv.java:586)
    at org.h2.tools.Csv.read(Csv.java:194)
    at org.h2.expression.function.Function.getValueForColumnList(Function.java:2728)
    at org.h2.table.FunctionTable.<init>(FunctionTable.java:60)
    at org.h2.command.Parser.readTableFunction(Parser.java:1945)
    at org.h2.command.Parser.readTableFilter(Parser.java:1892)
    at org.h2.command.Parser.parseSelectSimpleFromPart(Parser.java:2641)
    at org.h2.command.Parser.parseSelectSimple(Parser.java:2788)
    at org.h2.command.Parser.parseSelectSub(Parser.java:2636)
    at org.h2.command.Parser.parseSelectUnion(Parser.java:2469)
    at org.h2.command.Parser.parseSelect(Parser.java:2440)
    at org.h2.command.Parser.parseInsertGivenTable(Parser.java:1759)
    at org.h2.command.Parser.parseInsert(Parser.java:1684)
    at org.h2.command.Parser.parsePrepared(Parser.java:891)
    at org.h2.command.Parser.parse(Parser.java:788)
    at org.h2.command.Parser.parse(Parser.java:760)
    at org.h2.command.Parser.prepareCommand(Parser.java:683)
    at org.h2.engine.Session.prepareLocal(Session.java:627)
    at org.h2.engine.Session.prepareCommand(Session.java:565)
    at org.h2.jdbc.JdbcConnection.prepareCommand(JdbcConnection.java:1292)
    at org.h2.jdbc.JdbcPreparedStatement.<init>(JdbcPreparedStatement.java:77)
    at org.h2.jdbc.JdbcConnection.prepareStatement(JdbcConnection.java:349)
    at slick.jdbc.JdbcBackend$SessionDef.prepareStatement(JdbcBackend.scala:375)
    at slick.jdbc.JdbcBackend$SessionDef.prepareStatement$(JdbcBackend.scala:365)
    at slick.jdbc.JdbcBackend$BaseSession.prepareStatement(JdbcBackend.scala:489)
    at slick.jdbc.StatementInvoker.results(StatementInvoker.scala:33)
    at slick.jdbc.StatementInvoker.iteratorTo(StatementInvoker.scala:22)
    at slick.jdbc.Invoker.first(Invoker.scala:30)
    at slick.jdbc.Invoker.first$(Invoker.scala:29)
    at slick.jdbc.StatementInvoker.first(StatementInvoker.scala:16)
    at slick.jdbc.StreamingInvokerAction$HeadAction.run(StreamingInvokerAction.scala:52)
    at slick.jdbc.StreamingInvokerAction$HeadAction.run(StreamingInvokerAction.scala:51)
    at slick.dbio.DBIOAction$$anon$4.$anonfun$run$3(DBIOAction.scala:239)
    at scala.collection.Iterator.foreach(Iterator.scala:941)
    at scala.collection.Iterator.foreach$(Iterator.scala:941)
    at scala.collection.AbstractIterator.foreach(Iterator.scala:1429)
    at scala.collection.IterableLike.foreach(IterableLike.scala:74)
    at scala.collection.IterableLike.foreach$(IterableLike.scala:73)
    at scala.collection.AbstractIterable.foreach(Iterable.scala:56)
    at slick.dbio.DBIOAction$$anon$4.run(DBIOAction.scala:239)
    at slick.dbio.DBIOAction$$anon$4.run(DBIOAction.scala:237)
    at slick.basic.BasicBackend$DatabaseDef$$anon$3.liftedTree1$1(BasicBackend.scala:276)
    at slick.basic.BasicBackend$DatabaseDef$$anon$3.run(BasicBackend.scala:276)
    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)
Caused by: java.io.FileNotFoundException: ? (No such file or directory)
    at java.io.FileInputStream.open0(Native Method)
    at java.io.FileInputStream.open(FileInputStream.java:195)
    at java.io.FileInputStream.<init>(FileInputStream.java:138)
    at java.io.FileInputStream.<init>(FileInputStream.java:93)
    at org.h2.store.fs.FilePathDisk.newInputStream(FilePathDisk.java:337)
    at org.h2.store.fs.FileUtils.newInputStream(FileUtils.java:224)
    at org.h2.tools.Csv.initRead(Csv.java:312)
    at org.h2.tools.Csv.readResultSet(Csv.java:216)
    at org.h2.tools.Csv.read(Csv.java:192)
    ... 44 more

问题

我如何fixbypass解决方法此行为,以便能够通过.csv路径作为参数

如果我将.csv路径直接放在CSVREAD字符串语句中,则一切正常。

sqlu"INSERT INTO SUPPLIERS SELECT * FROM CSVREAD('/home/foo/sample.csv')"

sqlu插值生效时发​​生了什么。

build.sbt

libraryDependencies ++= List(
  "com.typesafe.slick" %% "slick" % "3.3.2",
  "org.slf4j" % "slf4j-nop" % "1.7.10",
  "com.h2database" % "h2" % "1.4.199"
)

scala csv h2 slick
1个回答
0
投票

您需要将'$csvPath'替换为普通的$csvPath。 JDBC参数是值,不能包含在字符串文字中。

© www.soinside.com 2019 - 2024. All rights reserved.