Simba JDBC 用于与 Spark JDBC DataFrame reader 一起使用的 Cloud Spanner 的驱动程序
Simba JDBC driver For Cloud Spanner used with Spark JDBC DataFrame reader
我正在使用 Simba Technologies Inc 的 JDBC 驱动程序与 Google cloud spanner 建立连接。与预期的 Java.sql 一样,它是 运行。什么时候,我尝试将 simba JDBC 驱动程序与 Spark 的 JDBC reader 一起使用,以便将查询输出读取为 DataFrame 但是,它给出了错误的输出。
这是我的扳手table:
UserID UserName
1 Vaijnath
2 Ganesh
3 Rahul
元数据:
用户 ID(字符串)
用户名(字符串)
我正在执行 Query 作为:SELECT * FROM users
当我将 Simba JDBC 驱动程序与 Java Sql 一起使用时,此查询获取正确的数据,但当我将其与 Spark SQL 一起使用时,它无法获取数据' s JDBC reader.
它returns DataFrame 为
+------+--------+
|UserID|UserName|
+------+--------+
|UserID|UserName|
|UserID|UserName|
|UserID|UserName|
+------+--------+
正如我们所见,它返回了正确的元数据和行数,但是,行包含列名。
这是我使用的代码:
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)
}
}
我的问题是,我可以将 Simba JDBC 驱动程序与 Spark 一起使用吗?
如果是,那么我需要添加哪些额外的东西。
感谢任何帮助。
这是因为 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 驱动程序。
我正在使用 Simba Technologies Inc 的 JDBC 驱动程序与 Google cloud spanner 建立连接。与预期的 Java.sql 一样,它是 运行。什么时候,我尝试将 simba JDBC 驱动程序与 Spark 的 JDBC reader 一起使用,以便将查询输出读取为 DataFrame 但是,它给出了错误的输出。
这是我的扳手table:
UserID UserName
1 Vaijnath
2 Ganesh
3 Rahul
元数据:
用户 ID(字符串)
用户名(字符串)
我正在执行 Query 作为:SELECT * FROM users
当我将 Simba JDBC 驱动程序与 Java Sql 一起使用时,此查询获取正确的数据,但当我将其与 Spark SQL 一起使用时,它无法获取数据' s JDBC reader.
它returns DataFrame 为
+------+--------+
|UserID|UserName|
+------+--------+
|UserID|UserName|
|UserID|UserName|
|UserID|UserName|
+------+--------+
正如我们所见,它返回了正确的元数据和行数,但是,行包含列名。
这是我使用的代码:
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)
}
}
我的问题是,我可以将 Simba JDBC 驱动程序与 Spark 一起使用吗? 如果是,那么我需要添加哪些额外的东西。 感谢任何帮助。
这是因为 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 驱动程序。