在 Spark 中将 MS Access 表加载为 DataFrame

Posted

技术标签:

【中文标题】在 Spark 中将 MS Access 表加载为 DataFrame【英文标题】:Load MS Access table as DataFrame in Spark 【发布时间】:2018-10-15 09:46:59 【问题描述】:

我正在尝试从 MS Access 数据库加载表。

我是这样做的:

val table = sparkSession.read
    .format("jdbc")
    .option("url", "jdbc:ucanaccess://D:/User/test.mdf;memory=false")
    .option("dbtable", "my_table")
    .load()
    .toDF

我添加了这些依赖项

ucanaccess-4.0.1, hsqldb-2.4.1, jackcess-2.1.6, commons-lang3-3.8.1 commons-logging-1.2.

我得到了这个例外:

Caused by: net.ucanaccess.jdbc.UcanaccessSQLException: UCAExc:::4.0.1 incompatible data type in conversion: from SQL type CHARACTER to java.lang.Integer, value: Maj_ID
at net.ucanaccess.jdbc.UcanaccessResultSet.getInt(UcanaccessResultSet.java:447)
at org.apache.spark.sql.execution.datasources.jdbc.JdbcUtils$$anonfun$org$apache$spark$sql$execution$datasources$jdbc$JdbcUtils$$makeGetter$6.apply(JdbcUtils.scala:411)
at org.apache.spark.sql.execution.datasources.jdbc.JdbcUtils$$anonfun$org$apache$spark$sql$execution$datasources$jdbc$JdbcUtils$$makeGetter$6.apply(JdbcUtils.scala:410)
at org.apache.spark.sql.execution.datasources.jdbc.JdbcUtils$$anon$1.getNext(JdbcUtils.scala:347)
at org.apache.spark.sql.execution.datasources.jdbc.JdbcUtils$$anon$1.getNext(JdbcUtils.scala:329)
at org.apache.spark.util.NextIterator.hasNext(NextIterator.scala:73)

【问题讨论】:

您不使用 ucanaccess-4.0.4 有什么原因吗?查看更改日志,至少有一个与 CHAR 相关的问题自 4.0.1 以来已修复 - 我并不是说这是您的修复,但检查是否是这种情况应该很简单。 我同意@SimonGroenewolt - 下载the latest version of UCanAccess,运行console.batconsole.sh,加载数据库文件,看看UCanAccess 是否报告任何错误。如果没有,请尝试SELECT * FROM my_table; 看看是否有效。 【参考方案1】:

我遇到了同样的问题,找到了答案here。

这是由于 net.ucanaccess.jdbc.UcanaccessDriver 在 Apache Spark 中没有专用的 JDBC 方言,因此它回退到具有用于列转义的双引号的默认方言,然后将它们视为字符串文字。显然,列应该用反引号字符转义。

在最新版本的 Spark 中(肯定可以在 Spark 2.4 和 3.x 中工作),您只需像这样注册方言来修复它:

import org.apache.spark.sql.jdbc.JdbcDialect, JdbcDialects

object UcanaccessDialect extends JdbcDialect 
  override def canHandle(url: String): Boolean =
    url.toLowerCase(java.util.Locale.ROOT).startsWith("jdbc:ucanaccess")
  override def quoteIdentifier(colName: String): String = s"`$colName`"

【讨论】:

以上是关于在 Spark 中将 MS Access 表加载为 DataFrame的主要内容,如果未能解决你的问题,请参考以下文章

如何在 MS Access 的追加查询中将数据类型从文本转换为是/否?

在 ms access 2010 中将查询结果插入表中

当用户在 MS Access 中修改表中的另一列时,如何在 SQL Server 中将列设置为今天的日期 [关闭]

从 MS Access 中将交叉表查询结果导出到 Excel

如何在拆分数据库中将表从前端链接到后端(MS Access 2010)

在列表框 ms-access 2013 VBA 中将多个不同的字段作为列表项返回