这个问题的目的是记录:
在PySpark中使用JDBC连接读取和写入数据所需的步骤
JDBC源可能存在的问题以及已知的解决方案
只要稍作更改,这些方法就可以与其他支持的语言一起使用,包括Scala和R。
Answers:
提交应用程序或启动Shell时,包括适用的JDBC驱动程序。您可以使用例如--packages
:
bin/pyspark --packages group:name:version
或结合driver-class-path
和jars
bin/pyspark --driver-class-path $PATH_TO_DRIVER_JAR --jars $PATH_TO_DRIVER_JAR
也可以PYSPARK_SUBMIT_ARGS
在启动JVM实例之前使用环境变量来设置这些属性,或使用conf/spark-defaults.conf
setspark.jars.packages
或spark.jars
/来设置这些属性spark.driver.extraClassPath
。
选择所需的模式。Spark JDBC编写器支持以下模式:
append
:将此:class:的内容追加DataFrame
到现有数据中。overwrite
:覆盖现有数据。ignore
:如果数据已经存在,请静默忽略此操作。error
(默认情况):如果数据已经存在,则引发异常。
不支持更新或其他细粒度的修改
mode = ...
准备JDBC URI,例如:
# You can encode credentials in URI or pass
# separately using properties argument
# of jdbc method or options
url = "jdbc:postgresql://localhost/foobar"
(可选)创建JDBC参数字典。
properties = {
"user": "foo",
"password": "bar"
}
properties
/options
还可以用于设置支持的JDBC连接属性。
采用 DataFrame.write.jdbc
df.write.jdbc(url=url, table="baz", mode=mode, properties=properties)
保存数据(pyspark.sql.DataFrameWriter
有关详细信息,请参阅)。
已知问题:
使用--packages
(java.sql.SQLException: No suitable driver found for jdbc: ...
)包含驱动程序后,找不到合适的驱动程序
假设没有驱动程序版本不匹配可以解决此问题,则可以将driver
类添加到中properties
。例如:
properties = {
...
"driver": "org.postgresql.Driver"
}
使用df.write.format("jdbc").options(...).save()
可能会导致:
java.lang.RuntimeException:org.apache.spark.sql.execution.datasources.jdbc.DefaultSource不允许创建表为select。
解决方案未知。
在Pyspark 1.3中,您可以尝试直接调用Java方法:
df._jdf.insertIntoJDBC(url, "baz", True)
用途sqlContext.read.jdbc
:
sqlContext.read.jdbc(url=url, table="baz", properties=properties)
或sqlContext.read.format("jdbc")
:
(sqlContext.read.format("jdbc")
.options(url=url, dbtable="baz", **properties)
.load())
已知问题和陷阱:
Spark SQL支持JDBC源的谓词下推,尽管并非所有谓词都可以下推。它也没有委派限制或聚合。可能的解决方法是用有效的子查询替换dbtable
/table
参数。参见例如:
默认情况下,JDBC数据源使用单个执行程序线程顺序加载数据。为确保分布式数据加载,您可以:
column
(必须IntegeType
)lowerBound
,upperBound
,numPartitions
。predicates
每个所需分区一个。看到:
在分布式模式(具有分区列或谓词)中,每个执行程序都在其自己的事务中运行。如果同时修改源数据库,则不能保证最终视图将保持一致。
Maven存储库(以获取用于--packages
选择所需版本的所需坐标,并从Gradle选项卡中以compile-group:name:version
替换各个字段的形式复制数据)或Maven Central存储库:
根据数据库的不同,可能存在专门的来源,并且在某些情况下是首选的来源:
下载mysql-connector-java驱动程序并保存在spark jar文件夹中,请注意下面的python代码,将数据写入“ acotr1”,我们必须在mysql数据库中创建acotr1表结构
spark = SparkSession.builder.appName("prasadad").master('local').config('spark.driver.extraClassPath','D:\spark-2.1.0-bin-hadoop2.7\jars\mysql-connector-java-5.1.41-bin.jar').getOrCreate()
sc = spark.sparkContext
from pyspark.sql import SQLContext
sqlContext = SQLContext(sc)
df = sqlContext.read.format("jdbc").options(url="jdbc:mysql://localhost:3306/sakila",driver="com.mysql.jdbc.Driver",dbtable="actor",user="root",password="****").load()
mysql_url="jdbc:mysql://localhost:3306/sakila?user=root&password=****"
df.write.jdbc(mysql_url,table="actor1",mode="append")
请参考此链接下载用于postgres的jdbc,并按照步骤下载jar文件
这样的路径中将下载https://jaceklaskowski.gitbooks.io/mastering-apache-spark/exercises/spark-exercise-dataframe-jdbc-postgresql.html jar文件。“ /home/anand/.ivy2/jars/org.postgresql_postgresql-42.1.1.jar”
如果您的Spark版本是2
from pyspark.sql import SparkSession
spark = SparkSession.builder
.appName("sparkanalysis")
.config("spark.driver.extraClassPath",
"/home/anand/.ivy2/jars/org.postgresql_postgresql42.1.1.jar")
.getOrCreate()
//for localhost database//
pgDF = spark.read \
.format("jdbc") \
.option("url", "jdbc:postgresql:postgres") \
.option("dbtable", "public.user_emp_tab") \
.option("user", "postgres") \
.option("password", "Jonsnow@100") \
.load()
print(pgDF)
pgDF.filter(pgDF["user_id"]>5).show()
将文件另存为python并运行“ python各自filename.py”