2016-02-26 21 views
11

Ich benutze PySpark auf Spark 1.5 auf Cloudera YARN, mit Python 3.3 auf Centos 6 Maschinen. Die SQL Server-Instanz ist SQL Server Enterprise 64bit. Der SQL Server-Treiber ist unten aufgeführt; sqljdbc4.jar; und ich habe hinzugefügt, um meine BashrcPySpark 1.5 & MSSQL jdbc

export SPARK_CLASSPATH="/var/lib/spark/sqljdbc4.jar" 
export PYSPARK_SUBMIT_ARGS="--conf spark.executor.extraClassPath="/var/lib/spark/sqljdbc4.jar" --driver-class-path="/var/lib/spark/sqljdbc4.jar" --jars="/var/lib/spark/sqljdbc4.jar" --master yarn --deploy-mode client" 

Und ich kann Bestätigung sehen, wenn ich Funken starten, dass

SPARK_CLASSPATH was detected (set to '/var/lib/spark/sqljdbc4.jar') 

ich einen Datenrahmen, die wie dieses Schema sieht

root 
|-- daytetime: timestamp (nullable = true) 
|-- ip: string (nullable = true) 
|-- tech: string (nullable = true) 
|-- th: string (nullable = true) 
|-- car: string (nullable = true) 
|-- min_dayte: timestamp (nullable = true) 
|-- max_dayte: timestamp (nullable = true) 

Ich habe Ich habe bereits eine leere Tabelle in meinem MS SQL Server mit dem Namen 'dbo.shaping' erstellt, wobei die 3 Zeitstempelspalten datetime2 (7) und die anderen nvarchar (50) sein werden.

Ich versuche, den Datenrahmen von PySpark zu exportieren diesen

properties = {"user": "<username>", "password": "<password>"} 

df.write.format('jdbc').options(url='<IP>:1433/<dbname>', dbtable='dbo.shaping',driver="com.microsoft.sqlserver.jdbc.SQLServerDriver",properties=properties) 

mit erhalte ich die folgenden Zurückverfolgungsfehler

Py4JError: An error occurred while calling o250.option. Trace: 
py4j.Py4JException: Method option([class java.lang.String, class java.util.HashMap]) does not exist 
at py4j.reflection.ReflectionEngine.getMethod(ReflectionEngine.java:333) 
at py4j.reflection.ReflectionEngine.getMethod(ReflectionEngine.java:342) 
at py4j.Gateway.invoke(Gateway.java:252) 
at py4j.commands.AbstractCommand.invokeMethod(AbstractCommand.java:133) 
at py4j.commands.CallCommand.execute(CallCommand.java:79) 
at py4j.GatewayConnection.run(GatewayConnection.java:207) 
at java.lang.Thread.run(Thread.java:744) 

meine Methoden zumindest korrekt sind, und vielleicht wird dieser Fehler im Zusammenhang der zum Schreiben spezifische Art von Daten, dh ich habe ein Problem mit dem Datenkonstrukt und nicht mit meinem Code?

+1

Sie eine Frage wieder zu beleben, die älter als ein Jahr ist. Haben Sie verifiziert, dass es immer noch relevant ist, wenn Sie gefragt werden (angesichts von Dingen wie neueren Versionen von Software)? –

+0

Softwareaktualisierungen sind auf dieser Infra nicht möglich. Muss pyspark 1.5 Lösung sein. – PR102012

+1

pyspark 1.5 ist eine Sache, aber der Microsoft JDBC-Treiber für SQL Server wurde ebenfalls aktualisiert. Ihr Fehler weist alle Kennzeichen eines Versionskonflikts zwischen Komponenten auf, es ist einfach nicht klar, welche. Ich empfehle, die Versionsnummern von allem, was Sie verwenden (python, pyspark, JDBC-Treiber, SQL Server, OS), explizit aufzulisten, sonst besteht wenig Hoffnung, dass jemand es reproduziert. (Deshalb bin ich auch skeptisch, dass dies "weit verbreitet für ein großes Publikum ist", aber ich habe keine Erfahrung mit pyspark.) –

Antwort

6

Sie können dict nicht als Wert für options verwenden. options Methode erwartet nur str Argumente (Scala docs und PySpark annotations) und wird erweitert, um Aufrufe an Java option zu trennen.

In den aktuellen Spark-Versionen ist der Wert automatically converted to string, daher würde Ihr Code stumm ausfallen, aber it isn't the case in 1.5.

Da properties sind spezifisch für JDBC-Treiber wie auch immer, sollten Sie jdbc Methode verwenden:

properties = { 
    "user": "<username>", "password": "<password>", "driver": 
    "com.microsoft.sqlserver.jdbc.SQLServerDriver"} 

df.write.jdbc(
    url='<IP>:1433/<dbname>', 
    table='dbo.shaping', 
    properties=properties) 

obwohl Auspacken Eigenschaften sollten auch funktionieren:

.options(
    url='<IP>:1433/<dbname>', 
    dbtable='dbo.shaping', 
    driver="com.microsoft.sqlserver.jdbc.SQLServerDriver", 
    **properties) 

Im Allgemeinen, wenn Sie sehen:

py4j.Py4JException: Method ... does not exist 

es signalisiert normalerweise Mismatch zwischen loc al Python-Typen und die Typen, die von der verwendeten JVM-Methode erwartet werden.

Siehe auch: How to use JDBC source to write and read data in (Py)Spark?

+0

Ich schließe die Eigenschaften für "user", "password" und "driver" ein; wie du hier hast.Allerdings erhalte ich jetzt den Fehler 'Py4JJavaError: Beim Aufruf von o230.jdbc ist ein Fehler aufgetreten. : java.sql.SQLException: Es wurde kein geeigneter Treiber für 'gefunden. .. Ist es möglich b/c Ich bin auf YARN, dass die .jar-Datei, die der Treiber und in meinem .bashrc auf meinem Mgmt/Execution-Knoten enthalten ist, nicht in dem gleichen Verzeichnis in jedem anderen Nicht-Master-Knoten ist? Wenn ich also mehrere Knoten verwende, haben einige das Glas nicht? – PR102012

+0

JDBC-Treiber muss auf jedem Worker-Knoten vorhanden sein. Persönlich würde ich die Option "--packages" verwenden, die im Client-Modus gedacht ist. Sie sollten in der Lage sein, ein lokales Jar mit '--jars' zu übergeben. – zero323