Simba JDBC驱动程序For Cloud Spanner与Spark JDBC DataFrame阅读器一起使用

时间:2017-06-29 12:19:22

标签: apache-spark apache-spark-sql google-cloud-platform google-cloud-spanner

我正在使用Simba Technologies Inc的JDBC驱动程序与Google云扳手建立联系。它与Java.sql一起运行。什么时候,我尝试将simba JDBC驱动程序与Spark的JDBC阅读器一起使用,以便将查询输出作为DataFrame读取,但是它输出错误。

这是我的扳手表

UserID  UserName
1   Vaijnath
2   Ganesh
3   Rahul

的元数据: 用户名(字符串)
用户名(字符串)

我正在执行查询:SELECT * FROM users

当我使用带有Java Sql的Simba JDBC驱动程序时,此查询获取正确的数据,但是当我将它与Spark SQL的JDBC阅读器一起使用时,它无法获取数据。

将DataFrame作为

返回
+------+--------+
|UserID|UserName|
+------+--------+
|UserID|UserName|
|UserID|UserName|
|UserID|UserName|
+------+--------+

正如我们所看到的,它返回正确的元数据和行数,但是,row包含列名。

以下是我正在使用的代码:

import java.util.Properties
import org.apache.spark.sql.{DataFrame, SparkSession}

object  spannerIn {
    val sparkSession =SparkSession
            .builder()
            .appName("Spark SQL basic example").master("local")
            .config("spark.sql.warehouse.dir", "file:///tmp")
            .config("spark.sql.shuffle.partitions", 1)
            .getOrCreate()

    val properties =new Properties()
    properties.setProperty("user", "")
    properties.setProperty("password", "")
    properties.setProperty("driver", "com.simba.cloudspanner.core.jdbc42.CloudSpanner42Driver")

    val connectionURL="jdbc:cloudspanner://localhost;Project=abc;Instance=pqr;Database=xyz;PvtKeyPath=FilePath"
    val selectQuery="(select * from users)"
    def main(args: Array[String]): Unit = {
            val df = createJdbcDataframe()
            df.show()
    }
    def createJdbcDataframe(): DataFrame = {
    sparkSession.read.jdbc(connectionURL, selectQuery, properties)
    }
}

我的问题是,我可以在Spark中使用Simba JDBC Driver吗? 如果是,那么我需要添加多少额外的东西。 任何帮助赞赏。

1 个答案:

答案 0 :(得分:3)

这是因为Spark默认使用双引号引用所有标识符("),这意味着正在生成以下查询:

SELECT "UserID", "UserName" FROM USERS

Cloud Spanner将其解释为选择两个固定字符串。它在大多数其他数据库中与此基本相同:

SELECT 'UserID', 'UserName' FROM USERS

Google Cloud Spanner使用反引号(`)来引用标识符,并期望:

SELECT `UserID`, `UserName` FROM USERS

要解决此问题,您需要为Google Cloud Spanner注册特定的JDBC方言,并注册反引号以进行引用,如下所示:

    Class.forName("nl.topicus.jdbc.CloudSpannerDriver");
    SparkSession spark = SparkSession.builder().appName("Java Spark SQL basic example")
                .config("spark.some.config.option", "some-value").master("local").getOrCreate();
    String sparkURL = "jdbc:cloudspanner://localhost;Project=project-id;Instance=instance-id;Database=db;PvtKeyPath=pathToKeyFile.json";
    JdbcDialects.registerDialect(new JdbcDialect()
    {
        private static final long serialVersionUID = 1L;

        @Override
        public boolean canHandle(String url)
        {
            return url.toLowerCase().startsWith("jdbc:cloudspanner:");
        }

        @Override
        public String quoteIdentifier(String column)
        {
            return "`" + column + "`";
        }
    });
    Dataset<Row> dataset = spark.read().jdbc(sparkURL, "ACCOUNT", new Properties());
    dataset.show();

请注意,我没有使用Simba驱动程序测试上述内容,但只使用此驱动程序:https://github.com/olavloite/spanner-jdbc 我想它也适用于Simba驱动程序。