[转帖]使用JAYDEBEAPI同时连接两个不同数据库(ORACLE+MYSQL)的问题
jaydebeapi 同时连接两种数据库
在使用jaydebeapi只连接一种数据库时,是没问题的,但是如果需要同时连接两种数据库,比如同时连接oracle和mysql
例如以下测试代码:
- import jaydebeapi ##使用jdbc驱动连接数据库
- import pandas as pd
- dirver='oracle.jdbc.driver.OracleDriver'
- jarFile='D:\\WORK\\PYScript\\BiDataMonitor\\jdbc\\64\\ojdbc14.jar'
- addr_='xxx.xxx.xxx.xxx'+':'+'1521'+'/'+'xxx'
- url='jdbc:oracle:thin:@'+addr_
- print('url',url)
- DBUser='用户名'
- DBPwd='密码'
- conn=jaydebeapi.connect(dirver,[url,DBUser,DBPwd],jarFile) ##使用jdbc驱动连接数据库
- sql_str="select 'oracle' from dual"
- df=pd.read_sql_query(sql_str,conn)
- print(df)
- conn.close()
- dirver='com.mysql.jdbc.Driver'
- jarFile='D:\\WORK\\PYScript\\BiDataMonitor\\jdbc\\64\\mysql-connector-java-5.1.30.jar'
- addr_='xxx.xxx.xxx.xxx'+':'+'3306'+'/'+'xxx'
- url='jdbc:mysql://'+addr_
- print('url',url)
- DBUserMySql='用户名'
- DBPwdMySql='密码'
- conn2=jaydebeapi.connect(dirver,[url,DBUserMySql,DBPwdMySql],jarFile)
- sql_str="select 'mysql' from dual"
- df=pd.read_sql_query(sql_str,conn2)
- print(df)
- conn2.close()
在连接第二种数据库时,就会报错误:
- Py4JJavaError: An error occurred while calling z:java.sql.DriverManager.getConnection.
- : java.sql.SQLException: No suitable driver found for jdbc:mysql://10.1.164.5:3306/vvm
- at java.sql.DriverManager.getConnection(Unknown Source)
- at java.sql.DriverManager.getConnection(Unknown Source)
- at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
- at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
- at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
- at java.lang.reflect.Method.invoke(Unknown Source)
- at py4j.reflection.MethodInvoker.invoke(MethodInvoker.java:244)
- at py4j.reflection.ReflectionEngine.invoke(ReflectionEngine.java:357)
- at py4j.Gateway.invoke(Gateway.java:282)
- at py4j.commands.AbstractCommand.invokeMethod(AbstractCommand.java:132)
- at py4j.commands.CallCommand.execute(CallCommand.java:79)
- at py4j.GatewayConnection.run(GatewayConnection.java:214)
- at java.lang.Thread.run(Unknown Source)
错误信息中显示,找不到渠道,而实际上并不是驱动或者jar包的问题。
要分析和解决这个问题,还需要从jaydebeapi的源码中分析,打开jaydebeapi源码(下载地址:https://pypi.python.org/pypi/JayDeBeApi3),从报错信息中我们可以得到,是在...jaydebeapi\__init__.py", line 68

jaydebeapi.connect方法源码如下:
- # DB-API 2.0 Module Interface connect constructor
- def connect(jclassname, driver_args, jars=None, libs=None):
- """Open a connection to a database using a JDBC driver and return
- a Connection instance.
- jclassname: Full qualified Java class name of the JDBC driver.
- driver_args: Argument or sequence of arguments to be passed to the
- Java DriverManager.getConnection method. Usually the
- database URL. See
- http://docs.oracle.com/javase/6/docs/api/java/sql/DriverManager.html
- for more details
- jars: Jar filename or sequence of filenames for the JDBC driver
- libs: Dll/so filenames or sequence of dlls/sos used as shared
- library by the JDBC driver
- """
- if _gateway_is_running():
- gateway = java_gateway.JavaGateway()
- else:
- driver_args = [driver_args] if isinstance(driver_args, str) else driver_args
- if jars:
- classpath = os.pathsep.join(jars) if isinstance(jars, list) else jars
- else:
- classpath = None
- if libs:
- javaopts = libs if isinstance(libs, list) else [libs]
- else:
- javaopts = []
- gateway = java_gateway.JavaGateway.launch_gateway(
- port=25333, classpath=classpath, javaopts=javaopts, die_on_exit=True)
- java_gateway.java_import(gateway.jvm, 'java.sql.DriverManager')
- gateway.jvm.Class.forName(jclassname)
- connection = gateway.jvm.DriverManager.getConnection(*driver_args)
- if _converters is None:
- types_map = {}
- for type in gateway.jvm.Class.forName("java.sql.Types").getFields():
- types_map[type.getName()] = type.getInt(None)
- _init_converters(types_map)
- return Connection(connection, _converters)
报错信息中提示的68行也就是:
connection = gateway.jvm.DriverManager.getConnection(*driver_args)
其实,我不需要跟深层次是剖析,只需要分析下jaydebeapi.connect方法即可,该方法大概是逻辑是:
- 判断 java_gateway是否running
- |----------是---|-----否-----|
- | |
- 获取gateway实例 1、初始化参数
- 2、创建gateway实例
问题就出在这里,第一次连接oracle时,通过右边分支先初始化参数,然后创建了gateway实例,但是第二次调用jaydebeapi.connect方法连mysql时,由于_gateway_is_running()返回真,所以走左边分支,直接获取了上一次连接oracle时创建gateway实例,其中最重要的两个个参数jclassname和classpath,也就是“oracle.jdbc.driver.OracleDriver”和"ojdbc14.jar"
- gateway = java_gateway.JavaGateway.launch_gateway(
- port=25333, classpath=classpath, javaopts=javaopts, die_on_exit=True)
- java_gateway.java_import(gateway.jvm, 'java.sql.DriverManager')
- gateway.jvm.Class.forName(jclassname)
而第二次连mysql时,用的是mysql的连接,所以当然就是报No suitable driver found for jdbc错误。
明白了报错的原因,下面就来需求解决方法
解决的方法应该有多种,我这里采取了最简单,最暴力的方法,就是在判断_gateway_is_running()时,将其关闭,然后重新重建新的gateway实例,这样虽然简单,但是如果频繁连接数据库时,就会因为不能重用上一次实例而消耗额外的资源。
通过帮助函数可知,gateway实例有一个shutdown方法
修改后的connect方法如下:
- # DB-API 2.0 Module Interface connect constructor
- def connect(jclassname, driver_args, jars=None, libs=None):
- """Open a connection to a database using a JDBC driver and return
- a Connection instance.
- jclassname: Full qualified Java class name of the JDBC driver.
- driver_args: Argument or sequence of arguments to be passed to the
- Java DriverManager.getConnection method. Usually the
- database URL. See
- http://docs.oracle.com/javase/6/docs/api/java/sql/DriverManager.html
- for more details
- jars: Jar filename or sequence of filenames for the JDBC driver
- libs: Dll/so filenames or sequence of dlls/sos used as shared
- library by the JDBC driver
- """
- if _gateway_is_running():
- gateway = java_gateway.JavaGateway()
- gateway.shutdown()
- else:
- pass
- driver_args = [driver_args] if isinstance(driver_args, str) else driver_args
- if jars:
- classpath = os.pathsep.join(jars) if isinstance(jars, list) else jars
- else:
- classpath = None
- if libs:
- javaopts = libs if isinstance(libs, list) else [libs]
- else:
- javaopts = []
- gateway = java_gateway.JavaGateway.launch_gateway(
- port=25333, classpath=classpath, javaopts=javaopts, die_on_exit=True)
- java_gateway.java_import(gateway.jvm, 'java.sql.DriverManager')
- gateway.jvm.Class.forName(jclassname)
- connection = gateway.jvm.DriverManager.getConnection(*driver_args)
- if _converters is None:
- types_map = {}
- for type in gateway.jvm.Class.forName("java.sql.Types").getFields():
- types_map[type.getName()] = type.getInt(None)
- _init_converters(types_map)
- return Connection(connection, _converters)
然后卸载jaydebeapi,用修改后的源码重新安装一次即可,源码安装方法,可以查看之前的一篇博客:
[转帖]使用JAYDEBEAPI同时连接两个不同数据库(ORACLE+MYSQL)的问题的更多相关文章
- Linq to Entity中连接两个数据库时要注意的问题
Linq to Entity中连接两个数据库时要注意的问题 今天大学同学问了我一个问题,Linq to Entity中连接两个数据库时,报错“指定的 LINQ 表达式包含对与不同上下文关联的查询的引用 ...
- Springboot配置连接两个数据库
背景: 项目中需要从两个不同的数据库查询数据,之前实现方法是:springboot配置连接一个数据源,另一个使用jdbc代码连接. 为了改进,现在使用SpringBoot配置连接两个数据源 实现效果: ...
- JavaScript concat() 方法-连接两个或多个数组
一,定义和用法 concat() 方法用于连接两个或多个数组. 该方法不会改变现有的数组,而仅仅会返回被连接数组的一个副本. 语法 arrayObject.concat(arrayX,arrayX,. ...
- Android 通过外键连接两个数据库
Learn: 1.Android数据库的语法. 2.通过外键连接两个数据库. 3.加强了对数据库的熟悉度. 4.对文本框的visiblity属性的了解. Demo:http://pan.baidu.c ...
- DirectX:函数连接两个随机filter
函数连接两个随机filter HRESULT ConnectFilters( IBaseFilter *pSrc, IBaseFilter *pDest ) { IPin *pIn = 0; IPin ...
- mysql 连接两列
以下划线符号,连接两列,作为查询结果: SELECT CONCAT(col_1,'_',col_2) FROM yourtable
- 连接两个点云中的字段或数据形成新点云以及Opennni Grabber初识
(1)学习如何连接两个不同点云为一个点云,进行操作前要确保两个数据集中字段的类型相同和维度相等,同时了解如何连接两个不同点云的字段(例如颜色 法线)这种操作的强制约束条件是两个数据集中点的数目必须一样 ...
- [转载]INNER JOIN连接两个表、三个表、五个表的SQL语句
SQL INNER JOIN关键字表示在表中存在至少一个匹配时,INNER JOIN 关键字返回行. 1.连接两个数据表的用法: FROM Member INNER JOIN MemberSort O ...
- 怎么用ChemDraw连接两个结构片段
作为最新版的ChemOffice 15.1的核心组件,ChemDraw几乎能解决所有平面化学结构中的绘制问题.如果用户想连接两个分开的结构片段,ChemDraw提供两种连接两个化学结构片段的方法,分别 ...
- 这样才能使本地Mysql服务允许被外部主机连接(两步)
网上的N多方法都不全面,只有下面的第一步或第二步是不行的,必须同时执行下面两步操作: 修改mysql.user表 以root或debian-sys-maint身份登录mysql $ mysql -u ...
随机推荐
- spring-cloud-alibaba项目打包
在父依赖中加入 <build> <plugins> <plugin> <groupId>org.springframework.boot</gro ...
- maven系列:属性管理和版本管理
目录 一. 属性配置与使用 ①:定义属性 ②:引用属性 二. 资源文件引用属性 ①:定义属性 ②:配置文件中引用属性 ③:开启资源文件目录加载属性的过滤器 ④:配置maven打war包时,忽略web. ...
- DBA:介里有你没有用过的“CHUAN”新社区版本Redis6.0
摘要:华为云DCS Redis 6.0社区版带来了极致性能.功能全面.可靠性强.性价比高的云服务,并且完全兼容开源Redis,客户端无需修改代码,开通后即可使用,使企业完全无需后顾之忧就能享受到业务响 ...
- XEngine:深度学习模型推理优化
摘要:从显存优化,计算优化两个方面来分析一下如何进行深度学习模型推理优化. 本文分享自华为云社区<XEngine-深度学习推理优化>,作者: ross.xw. 前言 深度学习模型的开发周期 ...
- 实用指南:手把手搭建坚若磐石的DevSecOps框架
长期以来,安全问题一直被当作软件开发流程中的最后一步.开发者贡献可以实现软件特性的代码,但只在开发生命周期的测试和部署阶段考虑安全问题.随着盗版.恶意软件及网络犯罪事件飙升,开发流程需要做出改变. 开 ...
- 火山引擎DataLeap数据质量解决方案和最佳实践(二):解决方案
更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,回复[1]进入官方交流群 DataLeap流批数据质量解决方案 产品功能架构 火山引擎DataLeap流批数据质量解决方案有 4 个大的功能 ...
- 本地安装mysql (zip)
下载 https://downloads.mysql.com/archives/community/ 解压到文件夹且添加系统环境变量 C:\Dinstall\Dmysql\mysql-8.2.0-wi ...
- 文心一言 VS 讯飞星火 VS chatgpt (180)-- 算法导论13.4 3题
三.用go语言,在练习13.3-2 中,将关键字 41.38.31.12.19.8 连续插入一棵初始的空树中,从而得到一棵红黑树.请给出从该树中连续删除关键字 8.12.19.31.38.41 后的红 ...
- 基于分发与计算的GRTN全球实时传输网络
一张能同时满足「分发」与「计算」需求的网. 从直播趋势看「分发」与「计算」 阿里云直播产品架构图中,主要分为端和云两个部分:在端侧,主要包含推流端和播放端:在云侧,一是基于分布式节点构建的传输网,二是 ...
- #1016:Prime Ring Problem(经典DFS)
原题链接 题意:很容易理解,就是让你输出满足相邻的相加是素数的序列(注意不要重复) 思路就是深搜思想把每种情况遍历一次 代码实现: #include<iostream> #include& ...