Ich mache meine ersten eigenen Schritte mit Spark und Zeppelin und verstehe nicht, warum dieses Codebeispiel nicht funktioniert.Apache-Zeppelin/Spark: Warum kann ich mit diesem Codebeispiel nicht auf eine Remote-DB zugreifen
Erster Block:
%dep
z.reset() // clean up
z.load("/data/extraJarFiles/postgresql-9.4.1208.jar") // load a jdbc driver for postgresql
zweiten Block
%spark
// This code loads some data from a PostGreSql DB with the help of a JDBC driver.
// The JDBC driver is stored on the Zeppelin server, the necessary Code is transfered to the Spark Workers and the workers build the connection with the DB.
//
// The connection between table and data source is "lazy". So the data will only be loaded in the case that an action need them.
// With the current script means this the DB is queried twice. ==> Q: How can I keep a RDD in Mem or on disk?
import org.apache.spark.SparkContext
import org.apache.spark.SparkContext._
import org.apache.spark.SparkConf
import org.apache.spark.rdd.JdbcRDD
import java.sql.Connection
import java.sql.DriverManager
import java.sql.ResultSet
import org.apache.spark.sql.hive._
import org.apache.spark.sql._
val url = "jdbc:postgresql://10.222.22.222:5432/myDatabase"
val username = "postgres"
val pw = "geheim"
Class.forName("org.postgresql.Driver").newInstance // activating the jdbc driver. The jar file was loaded inside of the %dep block
case class RowClass(Id:Integer, Col1:String , Col2:String) // create a class with possible values
val myRDD = new JdbcRDD(sc, // SparkContext sc
() => DriverManager.getConnection(url,username,pw), // scala.Function0<java.sql.Connection> getConnection
"select * from tab1 where \"Id\">=? and \"Id\" <=? ", // String sql Important: we need here two '?' for the lower/upper Bounds vlaues
0, // long lowerBound = start value
10000, // long upperBound, = end value that is still included
1, // int numPartitions = the area is spitted into x sub commands.
// e.g. 0,1000,2 => first cmd from 0 ... 499, second cmd from 500..1000
row => RowClass(row.getInt("Id"),
row.getString("Col1"),
row.getString("Col2"))
)
myRDD.toDF().registerTempTable("Tab1")
// --- improved methode (not working at the moment)----
val prop = new java.util.Properties
prop.setProperty("user",username)
prop.setProperty("password",pw)
val tab1b = sqlContext.read.jdbc(url,"tab1",prop) // <-- not working
tab1b.show
Also, was ist das Problem.
Ich möchte eine Verbindung zu einer externen PostgreSql DB herstellen.
Block I fügt die erforderliche JAR-Datei für den DB hinzu und die ersten Zeilen des zweiten Blocks verwenden bereits das JAR und können einige Daten aus dem DB abrufen.
Aber der erste Weg ist hässlich, weil Sie die Daten selbst in eine Tabelle konvertieren müssen, also möchte ich die einfachere Methode am Ende des Skripts verwenden.
Aber ich erhalte die Fehlermeldung
java.sql.SQLException: Keine passenden Treiber für jdbc gefunden: postgresql: //10.222.22.222: 5432/mydatabase
Aber es ist die gleiche URL/der selbe Login/selbe PW aus dem obigen Code. Warum funktioniert das nicht?
Vielleicht hat jemand einen hilfreichen Hinweis für mich.
---- Aktualisierung: 24.3. 12:15 ---
Ich glaube nicht, dass das Laden der JAR nicht funktioniert. Ich fügte ein extra val db = DriverManager.getConnection(url, username, pw);
zum Testen hinzu. (Die Funktion, die innerhalb der Ausnahme fehlschlägt) Und das funktioniert gut.
Ein weiteres interessantes Detail. Wenn ich den% dep-Block und die Klassenzeile entferne, erzeugt der erste Block einen sehr ähnlichen Fehler. Gleiche Fehlermeldung; gleiche Funktion + Zeilennummer, die fehlschlägt, aber der Stapel von Funktionen ist ein bisschen anders.
Ich habe den Quellcode hier: http://code.metager.de/source/xref/openjdk/jdk8/jdk/src/share/classes/java/sql/DriverManager.java
Mein Problem in Zeile 689. Also, wenn alle Parameter in Ordnung sind, vielleicht kommt es aus dem isDriverAllowed()
Check?
Das Problem, das Sie haben, ist, dass Zeppelin den jdbc-Treiber für Postgres nicht geladen hat. Welche Version von Zeppelin benutzt du? – user1314742
Ich benutze "Zeppelin-0.5.6". Warum aber kann der erste Block auf die DB zugreifen und der zweite funktioniert nicht? Das fühlt sich an, als ob die Funktion 'z.load()' den jdbc zu einer Liste hinzufügt, die von der Funktion 'JdbcRDD()' durchsucht wird und von der 'sqlContext.read.jdbc()' -Funktion ignoriert wird. – Xaltos
Können Sie Folgendes versuchen: Fügen Sie in Ihrer Interpreter-Konfiguration die folgende Eigenschaft hinzu: 'spark.driver.extraClassPath' mit dem Wert'/data/extraJarFiles/postgresql-9.4.1208.jar'. Sie können auf die Interpreterkonfiguration zugreifen, indem Sie auf das oberste Banner von Zeppelin klicken -> Interpreter – user1314742