连接和测试来自 Python 的 JDBC 驱动程序
Connecting and testing a JDBC driver from Python
我正在尝试使用 Python 对我们的 JDBC 驱动程序进行一些测试。
最初弄清楚 JPype,我最终设法连接驱动程序并执行 select 查询,如下所示(复制通用片段):
from __future__ import print_function
from jpype import *
#Start JVM, attach the driver jar
jvmpath = 'path/to/libjvm.so'
classpath = 'path/to/JDBC_Driver.jar'
startJVM(jvmpath, '-ea', '-Djava.class.path=' + classpath)
# Magic line 1
driver = JPackage('sql').Our_Driver
# Initiating a connection via DriverManager()
jdbc_uri = 'jdbc:our_database://localhost:port/database','user', 'passwd')
conn = java.sql.DriverManager.getConnection(jdbc_uri)
# Executing a statement
stmt = conn.createStatement()
rs = stmt.executeQuery ('select top 10 * from some_table')
# Extracting results
while rs.next():
''' Magic #2 - rs.getStuff() only works inside a while loop '''
print (rs.getString('col_name'))
但是,我无法批量插入,这正是我想测试的。即使 executeBatch()
返回一个 jpype int[],这应该表明插入成功,table 也没有更新。
然后我决定试用 py4j。
我的困境 - 我很难弄清楚如何做与上述相同的事情。据说 py4j 不会自己启动 JVM,并且 Java 代码需要预先安排一个 GatewayServer(),所以我不确定它是否可行。
另一方面,有一个名为 py4jdbc 的库可以做到这一点。
我修改了 dbapi.py 代码,但不太了解流程,几乎卡住了。
如果有人知道如何使用 py4j 从 .jar 文件加载 JDBC 驱动程序,并且可以指出正确的方向,我将不胜感激。
在添加记录之后和检索之前添加提交。
conn.commit()
在 py4j 中,使用您各自的 JDBC uri:
from py4j.JavaGateway import java_gateway
# Open JVM interface with the JDBC Jar
jdbc_jar_path = '/path/to/jdbc_driver.jar'
gateway = java_gateway(classpath=jdbc_jar_path)
# Load the JDBC Jar
jdbc_class = "com.vendor.VendorJDBC"
gateway.jvm.class.forName(jdbc_class)
# Initiate connection
jdbc_uri = "jdbc://vendor:192.168.x.y:zzzz;..."
con = gateway.jvm.DriverManager.getConnection(jdbc_uri)
# Run a query
sql = "select this from that"
stmt = con.createStatement(sql)
rs = stmt.executeQuery()
while rs.next():
rs.getInt(1)
rs.getFloat(2)
.
.
rs.close()
stmt.close()
我在airflow遇到过类似的问题,我用teradata jdbc jar和jaydebeapi连接teradata数据库执行sql:
[root@myhost transfer]# cat test_conn.py
import jaydebeapi
from contextlib import closing
jclassname='com.teradata.jdbc.TeraDriver'
jdbc_driver_loc = '/opt/spark-2.3.1/jars/terajdbc4-16.20.00.06.jar,/opt/spark-2.3.1/jars/tdgssconfig-16.20.00.06.jar'
jdbc_driver_name = 'com.teradata.jdbc.TeraDriver'
host='my_teradata.address'
url='jdbc:teradata://' + host + '/TMODE=TERA'
login="teradata_user_name"
psw="teradata_passwd"
sql = "SELECT COUNT(*) FROM A_TERADATA_TABLE_NAME where month_key='202009'"
conn = jaydebeapi.connect(jclassname=jdbc_driver_name,
url=url,
driver_args=[login, psw],
jars=jdbc_driver_loc.split(","))
with closing(conn) as conn:
with closing(conn.cursor()) as cur:
cur.execute(sql)
print(cur.fetchall())
[root@myhost transfer]# python test_conn.py
[(7734133,)]
[root@myhost transfer]#
我正在尝试使用 Python 对我们的 JDBC 驱动程序进行一些测试。
最初弄清楚 JPype,我最终设法连接驱动程序并执行 select 查询,如下所示(复制通用片段):
from __future__ import print_function
from jpype import *
#Start JVM, attach the driver jar
jvmpath = 'path/to/libjvm.so'
classpath = 'path/to/JDBC_Driver.jar'
startJVM(jvmpath, '-ea', '-Djava.class.path=' + classpath)
# Magic line 1
driver = JPackage('sql').Our_Driver
# Initiating a connection via DriverManager()
jdbc_uri = 'jdbc:our_database://localhost:port/database','user', 'passwd')
conn = java.sql.DriverManager.getConnection(jdbc_uri)
# Executing a statement
stmt = conn.createStatement()
rs = stmt.executeQuery ('select top 10 * from some_table')
# Extracting results
while rs.next():
''' Magic #2 - rs.getStuff() only works inside a while loop '''
print (rs.getString('col_name'))
但是,我无法批量插入,这正是我想测试的。即使 executeBatch()
返回一个 jpype int[],这应该表明插入成功,table 也没有更新。
然后我决定试用 py4j。
我的困境 - 我很难弄清楚如何做与上述相同的事情。据说 py4j 不会自己启动 JVM,并且 Java 代码需要预先安排一个 GatewayServer(),所以我不确定它是否可行。
另一方面,有一个名为 py4jdbc 的库可以做到这一点。
我修改了 dbapi.py 代码,但不太了解流程,几乎卡住了。
如果有人知道如何使用 py4j 从 .jar 文件加载 JDBC 驱动程序,并且可以指出正确的方向,我将不胜感激。
在添加记录之后和检索之前添加提交。
conn.commit()
在 py4j 中,使用您各自的 JDBC uri:
from py4j.JavaGateway import java_gateway
# Open JVM interface with the JDBC Jar
jdbc_jar_path = '/path/to/jdbc_driver.jar'
gateway = java_gateway(classpath=jdbc_jar_path)
# Load the JDBC Jar
jdbc_class = "com.vendor.VendorJDBC"
gateway.jvm.class.forName(jdbc_class)
# Initiate connection
jdbc_uri = "jdbc://vendor:192.168.x.y:zzzz;..."
con = gateway.jvm.DriverManager.getConnection(jdbc_uri)
# Run a query
sql = "select this from that"
stmt = con.createStatement(sql)
rs = stmt.executeQuery()
while rs.next():
rs.getInt(1)
rs.getFloat(2)
.
.
rs.close()
stmt.close()
我在airflow遇到过类似的问题,我用teradata jdbc jar和jaydebeapi连接teradata数据库执行sql:
[root@myhost transfer]# cat test_conn.py
import jaydebeapi
from contextlib import closing
jclassname='com.teradata.jdbc.TeraDriver'
jdbc_driver_loc = '/opt/spark-2.3.1/jars/terajdbc4-16.20.00.06.jar,/opt/spark-2.3.1/jars/tdgssconfig-16.20.00.06.jar'
jdbc_driver_name = 'com.teradata.jdbc.TeraDriver'
host='my_teradata.address'
url='jdbc:teradata://' + host + '/TMODE=TERA'
login="teradata_user_name"
psw="teradata_passwd"
sql = "SELECT COUNT(*) FROM A_TERADATA_TABLE_NAME where month_key='202009'"
conn = jaydebeapi.connect(jclassname=jdbc_driver_name,
url=url,
driver_args=[login, psw],
jars=jdbc_driver_loc.split(","))
with closing(conn) as conn:
with closing(conn.cursor()) as cur:
cur.execute(sql)
print(cur.fetchall())
[root@myhost transfer]# python test_conn.py
[(7734133,)]
[root@myhost transfer]#