[转帖]使用JAYDEBEAPI同时连接两个不同数据库(ORACLE+MYSQL)的问题

使用,jaydebeapi,同时,连接,两个,不同,数据库,oracle,mysql,问题 · 浏览次数 : 0

小编点评

**生成内容时需要带简单的排版** **1. 使用格式化输出** 格式化输出可以帮助你输出内容时使用格式化输出格式,例如输出时间格式。 ```java System.out.println("2023-04-05 10:10:10"); ``` **2. 使用控制输出** 控制输出可以帮助你控制输出内容,例如控制输出流或输出内容到指定文件。 ```java System.out.println("控制输出内容"); ``` **3. 使用格式化输出** 格式化输出可以帮助你输出内容时使用格式化输出格式,例如输出时间格式。 ```java System.out.println("2023-04-05 10:10:10"); ``` **4. 使用格式化输出** 格式化输出可以帮助你输出内容时使用格式化输出格式,例如输出时间格式。 ```java System.out.println("2023-04-05 10:10:10"); ``` **5. 使用控制输出** 控制输出可以帮助你控制输出内容,例如控制输出流或输出内容到指定文件。 ```java System.out.println("控制输出内容"); ``` **6. 使用格式化输出** 格式化输出可以帮助你输出内容时使用格式化输出格式,例如输出时间格式。 ```java System.out.println("2023-04-05 10:10:10"); ``` **7. 使用格式化输出** 格式化输出可以帮助你输出内容时使用格式化输出格式,例如输出时间格式。 ```java System.out.println("2023-04-05 10:10:10"); ```

正文

jaydebeapi 同时连接两种数据库

 

在使用jaydebeapi只连接一种数据库时,是没问题的,但是如果需要同时连接两种数据库,比如同时连接oracle和mysql

例如以下测试代码:

  1.  
    import jaydebeapi ##使用jdbc驱动连接数据库
  2.  
    import pandas as pd
  3.  
     
  4.  
    dirver='oracle.jdbc.driver.OracleDriver'
  5.  
    jarFile='D:\\WORK\\PYScript\\BiDataMonitor\\jdbc\\64\\ojdbc14.jar'
  6.  
    addr_='xxx.xxx.xxx.xxx'+':'+'1521'+'/'+'xxx'
  7.  
    url='jdbc:oracle:thin:@'+addr_
  8.  
    print('url',url)
  9.  
    DBUser='用户名'
  10.  
    DBPwd='密码'
  11.  
    conn=jaydebeapi.connect(dirver,[url,DBUser,DBPwd],jarFile) ##使用jdbc驱动连接数据库
  12.  
    sql_str="select 'oracle' from dual"
  13.  
    df=pd.read_sql_query(sql_str,conn)
  14.  
    print(df)
  15.  
    conn.close()
  16.  
     
  17.  
     
  18.  
    dirver='com.mysql.jdbc.Driver'
  19.  
    jarFile='D:\\WORK\\PYScript\\BiDataMonitor\\jdbc\\64\\mysql-connector-java-5.1.30.jar'
  20.  
    addr_='xxx.xxx.xxx.xxx'+':'+'3306'+'/'+'xxx'
  21.  
    url='jdbc:mysql://'+addr_
  22.  
    print('url',url)
  23.  
    DBUserMySql='用户名'
  24.  
    DBPwdMySql='密码'
  25.  
    conn2=jaydebeapi.connect(dirver,[url,DBUserMySql,DBPwdMySql],jarFile)
  26.  
    sql_str="select 'mysql' from dual"
  27.  
    df=pd.read_sql_query(sql_str,conn2)
  28.  
    print(df)
  29.  
    conn2.close()

在连接第二种数据库时,就会报错误:

  1.  
    Py4JJavaError: An error occurred while calling z:java.sql.DriverManager.getConnection.
  2.  
    : java.sql.SQLException: No suitable driver found for jdbc:mysql://10.1.164.5:3306/vvm
  3.  
    at java.sql.DriverManager.getConnection(Unknown Source)
  4.  
    at java.sql.DriverManager.getConnection(Unknown Source)
  5.  
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  6.  
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
  7.  
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
  8.  
    at java.lang.reflect.Method.invoke(Unknown Source)
  9.  
    at py4j.reflection.MethodInvoker.invoke(MethodInvoker.java:244)
  10.  
    at py4j.reflection.ReflectionEngine.invoke(ReflectionEngine.java:357)
  11.  
    at py4j.Gateway.invoke(Gateway.java:282)
  12.  
    at py4j.commands.AbstractCommand.invokeMethod(AbstractCommand.java:132)
  13.  
    at py4j.commands.CallCommand.execute(CallCommand.java:79)
  14.  
    at py4j.GatewayConnection.run(GatewayConnection.java:214)
  15.  
    at java.lang.Thread.run(Unknown Source)

错误信息中显示,找不到渠道,而实际上并不是驱动或者jar包的问题。

要分析和解决这个问题,还需要从jaydebeapi的源码中分析,打开jaydebeapi源码(下载地址:https://pypi.python.org/pypi/JayDeBeApi3),从报错信息中我们可以得到,是在...jaydebeapi\__init__.py", line 68

jaydebeapi.connect方法源码如下:

  1.  
    # DB-API 2.0 Module Interface connect constructor
  2.  
    def connect(jclassname, driver_args, jars=None, libs=None):
  3.  
    """Open a connection to a database using a JDBC driver and return
  4.  
    a Connection instance.
  5.  
     
  6.  
    jclassname: Full qualified Java class name of the JDBC driver.
  7.  
    driver_args: Argument or sequence of arguments to be passed to the
  8.  
    Java DriverManager.getConnection method. Usually the
  9.  
    database URL. See
  10.  
    http://docs.oracle.com/javase/6/docs/api/java/sql/DriverManager.html
  11.  
    for more details
  12.  
    jars: Jar filename or sequence of filenames for the JDBC driver
  13.  
    libs: Dll/so filenames or sequence of dlls/sos used as shared
  14.  
    library by the JDBC driver
  15.  
    """
  16.  
     
  17.  
    if _gateway_is_running():
  18.  
    gateway = java_gateway.JavaGateway()
  19.  
    else:
  20.  
    driver_args = [driver_args] if isinstance(driver_args, str) else driver_args
  21.  
     
  22.  
    if jars:
  23.  
    classpath = os.pathsep.join(jars) if isinstance(jars, list) else jars
  24.  
    else:
  25.  
    classpath = None
  26.  
     
  27.  
    if libs:
  28.  
    javaopts = libs if isinstance(libs, list) else [libs]
  29.  
    else:
  30.  
    javaopts = []
  31.  
     
  32.  
    gateway = java_gateway.JavaGateway.launch_gateway(
  33.  
    port=25333, classpath=classpath, javaopts=javaopts, die_on_exit=True)
  34.  
     
  35.  
    java_gateway.java_import(gateway.jvm, 'java.sql.DriverManager')
  36.  
    gateway.jvm.Class.forName(jclassname)
  37.  
     
  38.  
    connection = gateway.jvm.DriverManager.getConnection(*driver_args)
  39.  
    if _converters is None:
  40.  
    types_map = {}
  41.  
    for type in gateway.jvm.Class.forName("java.sql.Types").getFields():
  42.  
    types_map[type.getName()] = type.getInt(None)
  43.  
    _init_converters(types_map)
  44.  
     
  45.  
    return Connection(connection, _converters)

报错信息中提示的68行也就是:

connection = gateway.jvm.DriverManager.getConnection(*driver_args)

其实,我不需要跟深层次是剖析,只需要分析下jaydebeapi.connect方法即可,该方法大概是逻辑是:

  1.  
    判断 java_gateway是否running
  2.  
                |----------是---|-----否-----|
  3.  
                | |
  4.  
    获取gateway实例     1、初始化参数
  5.  
        2、创建gateway实例

问题就出在这里,第一次连接oracle时,通过右边分支先初始化参数,然后创建了gateway实例,但是第二次调用jaydebeapi.connect方法连mysql时,由于_gateway_is_running()返回真,所以走左边分支,直接获取了上一次连接oracle时创建gateway实例,其中最重要的两个个参数jclassname和classpath,也就是“oracle.jdbc.driver.OracleDriver”和"ojdbc14.jar"

  1.  
    gateway = java_gateway.JavaGateway.launch_gateway(
  2.  
    port=25333, classpath=classpath, javaopts=javaopts, die_on_exit=True)
  3.  
     
  4.  
    java_gateway.java_import(gateway.jvm, 'java.sql.DriverManager')
  5.  
    gateway.jvm.Class.forName(jclassname)

而第二次连mysql时,用的是mysql的连接,所以当然就是报No suitable driver found for jdbc错误。

明白了报错的原因,下面就来需求解决方法

解决的方法应该有多种,我这里采取了最简单,最暴力的方法,就是在判断_gateway_is_running()时,将其关闭,然后重新重建新的gateway实例,这样虽然简单,但是如果频繁连接数据库时,就会因为不能重用上一次实例而消耗额外的资源。

通过帮助函数可知,gateway实例有一个shutdown方法

修改后的connect方法如下:

  1.  
    # DB-API 2.0 Module Interface connect constructor
  2.  
    def connect(jclassname, driver_args, jars=None, libs=None):
  3.  
    """Open a connection to a database using a JDBC driver and return
  4.  
    a Connection instance.
  5.  
     
  6.  
    jclassname: Full qualified Java class name of the JDBC driver.
  7.  
    driver_args: Argument or sequence of arguments to be passed to the
  8.  
    Java DriverManager.getConnection method. Usually the
  9.  
    database URL. See
  10.  
    http://docs.oracle.com/javase/6/docs/api/java/sql/DriverManager.html
  11.  
    for more details
  12.  
    jars: Jar filename or sequence of filenames for the JDBC driver
  13.  
    libs: Dll/so filenames or sequence of dlls/sos used as shared
  14.  
    library by the JDBC driver
  15.  
    """
  16.  
     
  17.  
    if _gateway_is_running():
  18.  
    gateway = java_gateway.JavaGateway()
  19.  
    gateway.shutdown()
  20.  
    else:
  21.  
    pass
  22.  
    driver_args = [driver_args] if isinstance(driver_args, str) else driver_args
  23.  
     
  24.  
    if jars:
  25.  
    classpath = os.pathsep.join(jars) if isinstance(jars, list) else jars
  26.  
    else:
  27.  
    classpath = None
  28.  
     
  29.  
    if libs:
  30.  
    javaopts = libs if isinstance(libs, list) else [libs]
  31.  
    else:
  32.  
    javaopts = []
  33.  
     
  34.  
    gateway = java_gateway.JavaGateway.launch_gateway(
  35.  
    port=25333, classpath=classpath, javaopts=javaopts, die_on_exit=True)
  36.  
     
  37.  
    java_gateway.java_import(gateway.jvm, 'java.sql.DriverManager')
  38.  
    gateway.jvm.Class.forName(jclassname)
  39.  
     
  40.  
    connection = gateway.jvm.DriverManager.getConnection(*driver_args)
  41.  
    if _converters is None:
  42.  
    types_map = {}
  43.  
    for type in gateway.jvm.Class.forName("java.sql.Types").getFields():
  44.  
    types_map[type.getName()] = type.getInt(None)
  45.  
    _init_converters(types_map)
  46.  
     
  47.  
    return Connection(connection, _converters)

 

然后卸载jaydebeapi,用修改后的源码重新安装一次即可,源码安装方法,可以查看之前的一篇博客:

https://blog.csdn.net/cakecc2008/article/details/79073181

与[转帖]使用JAYDEBEAPI同时连接两个不同数据库(ORACLE+MYSQL)的问题相似的内容:

[转帖]使用JAYDEBEAPI同时连接两个不同数据库(ORACLE+MYSQL)的问题

jaydebeapi 同时连接两种数据库 在使用jaydebeapi只连接一种数据库时,是没问题的,但是如果需要同时连接两种数据库,比如同时连接oracle和mysql 例如以下测试代码: import jaydebeapi ##使用jdbc驱动连接数据库 import pandas as pd d

[转帖]使用JMX服务监控Java程序性能

https://www.jianshu.com/p/3c3c836c1c20?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation 背景 单机收集服务器需要性能监控和测试。 JMX

[转帖]使用 tc netem 模拟网络异常

https://cizixs.com/2017/10/23/tc-netem-for-terrible-network/ 在某些情况下,我们需要模拟网络很差的状态来测试软件能够正常工作,比如网络延迟、丢包、乱序、重复等。linux 系统强大的流量控制工具 tc 能很轻松地完成,tc 命令行是 ipr

[转帖]使用 sysdig 进行监控和调试 linux 机器

https://cizixs.com/2017/04/27/sysdig-for-linux-system-monitor-and-analysis/ sysdig 简介 sysdig 官网 上对自己的介绍是: Open Source Universal System Visibility With

[转帖]使用MAT命令行工具生成堆dump分析文件

https://www.cnblogs.com/hellxz/p/use_mat_linux_command_line_generate_reports.html 写作目标 Java程序运行过程中,难免会出现 OOM,往往是在 JVM 启动参数中添加出现 OOM 时输出堆 dump(又名:堆转储、堆

[转帖]使用火焰图(FlameGraph)分析程序性能

火焰图概念 火焰图(FlameGraph)是 svg 格式的矢量图,是先通过 perf 等工具分析得到结果,并将该结果生成的具有不同层次且支持互动的图片,看起来就像是火焰,这也是它的名字的由来。表现形式如下所示: 需要注意以下几点: 纵向(Y 轴)高低不平,表示的是函数调用栈的深度。每一层都是一个函

[转帖]使用Prometheus和Grafana监控RabbitMQ集群 (使用RabbitMQ自带插件)

https://www.cnblogs.com/hahaha111122222/p/15683696.html 配置RabbitMQ集群 官方文档:https://www.rabbitmq.com/prometheus.html#quick-start 官方github地址:https://gith

[转帖]使用Flame Graph进行系统性能分析

http://t.zoukankan.com/arnoldlu-p-10148558.html 关键词:Flame Graph、perf、perl。 FlameGraph是由BrendanGregg开发的一款开源可视化性能分析工具,形象的成为火焰图。 从底向上像火苗一样逐渐变小,也反映了相互之间的包

[转帖]使用 nsenter、dig 和 tcpdump 调试 Kubernetes 网络问题

https://zhuanlan.zhihu.com/p/410217354 使用 nsenter、dig 和 tcpdump 调试 Kubernetes 网络问题 作为 Kubernetes 管理员,我经常发现自己需要调试应用程序和系统问题。我遇到的大多数问题都可以通过 Grafana 仪表板和

[转帖]使用ksar解析sar监控日志

http://t.zoukankan.com/mikeguan-p-6371278.html sar 是属于sysstat包中的一个工具 安装sysstat包后,默认创建一个/etc/cron.d/sysstat文件,其默认内容为: # run system activity accounting