3

Ich verwende den JDBC-Treiber von Simba Technologies Inc, um mit dem Google Cloud-Schlüssel zu verbinden. Es läuft wie erwartet mit Java.sql. Als ich versuchte, den Simba-JDBC-Treiber mit dem JDBC-Lesegerät von Spark zu verwenden, um die Abfrageausgabe als DataFrame zu lesen, gab es jedoch eine falsche Ausgabe.Simba JDBC-Treiber Für Cloud Spanner mit Spark verwendet JDBC DataFrame-Reader

Hier ist meine Schlüssel Tabelle:

UserID UserName 
1 Vaijnath 
2 Ganesh 
3 Rahul 

Metadata: UserID (String)
Username (String)

I Abfrage als ich ausführen: SELECT * FROM users

Diese Abfrage holt korrekte Daten, wenn ich Verwenden Sie den Simba JDBC-Treiber mit Java Sql, aber er kann keine Daten abrufen, wenn ich ihn mit dem JDBC-Reader von Spark SQL verwende.

Es gibt den Datenrahmen als

+------+--------+ 
|UserID|UserName| 
+------+--------+ 
|UserID|UserName| 
|UserID|UserName| 
|UserID|UserName| 
+------+--------+ 

Wie wir sehen können, ist es richtig Metadaten und Anzahl der Zeilen zurückgibt, aber Zeile enthält die Spaltennamen.

Hier ist der Code Ich verwende:

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) 
    } 
} 

Meine Frage ist, kann ich die Simba-JDBC-Treiber mit Funken verwenden? Wenn ja, welche zusätzlichen Dinge muss ich hinzufügen. Jede Hilfe geschätzt.

Antwort

2

Dies geschieht, weil Funken durch Standard Zitat all Bezeichner ein doppeltes Anführungszeichen (") verwendet wird, werden die folgende Abfrage Sinn erzeugt werden:

Dies wird durch Cloud-Spanner als die Auswahl von zwei festen Strings interpretiert
SELECT "UserID", "UserName" FROM USERS 

Es ist im Grunde. die gleiche wie dies in den meisten anderen Datenbanken:

SELECT 'UserID', 'UserName' FROM USERS 

Google Cloud Spanner verwendet Backticks (`) für die Quotierung Identifikatoren und erwartet dies:

SELECT `UserID`, `UserName` FROM USERS 

Um dies zu beheben, müssen Sie einen bestimmten JDBC-Dialekt für Google Cloud Spanner registrieren und die Graviszeichen für zitieren wie folgt registrieren:

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(); 

Bitte beachten Sie, dass ich die oben mit den Simba-Treiber nicht getestet haben, aber nur mit diesem Treiber: Ich denke, es sollte auch mit dem Simba-Treiber funktionieren.

Verwandte Themen