JayDeBeApi触发java.sql.SQLException: 找不到合适的驱动程序。

3
我正在尝试使用包JayDeBeApiPython 3中连接到Teradata数据库。这是使用FlaskFlask-Restplus的API项目的一部分。
以下是最小化可行的示例以重现此问题。在终端窗口中,键入以下命令设置您的工作站:
# Install JVM
sudo apt-get install default-jre

# Create Python virtual environment
sudo apt-get install python3-venv
python3 -m venv jdbc
source jdbc/bin/activate

# Install Python packages in virtual environment
pip3 install --upgrade pip
pip3 install jaydebeapi
pip3 install flask

创建一个名为app.py的文件,并使用以下内容填充:
from flask import Flask
import jaydebeapi

app = Flask(__name__)


def get_jdbc_connection():
    connection = jaydebeapi.connect(
        'com.teradata.jdbc.TeraDriver',
        'jdbc:teradata://edw-dev.company.org',
        {'user': 'LOGIN', 'password': 'PASSWORD', 'tmode': 'TERA', 'charset': 'UTF8'},
        '/home/alexis/teradataDriverJdbc.jar')
    return connection


@app.route('/hello/')
def hello_world():
    print('Init second connection')
    get_jdbc_connection()
    print('Success')
    return 'Hello world!'


if __name__ == '__main__':
    print('Init connection')
    test_connection = get_jdbc_connection()
    test_connection.close()
    print('Init connection closed')
    app.run(host='localhost', port=5000, threaded=True, debug=True)

在激活虚拟环境的终端窗口中,键入以下内容:

python3
>>> import app
>>> app.get_jdbc_connection()
<jaydebeapi.Connection object at 0x7f28ecb2ebe0>

上面的代码片段是有效的,方法get_jdbc_connection()返回一个连接对象。 现在尝试在Flask中运行它。在启用虚拟环境的终端窗口中,输入以下内容:
python3 app.py
Init connection
Init connection closed
 * Running on http://localhost:5000/ (Press CTRL+C to quit)
 * Restarting with stat
Init connection
Init connection closed
 * Debugger is active!
 * Debugger PIN: 301-429-987

在您的浏览器中,导航至http://localhost:5000/hello/

您将会看到如下错误信息,与我在上面第一条留言中复制的错误信息是相同的:

enter image description here

Init second connection
127.0.0.1 - - [08/Mar/2018 16:00:30] "GET /hello/ HTTP/1.1" 500 -
Traceback (most recent call last):
  File "/home/alexis/dq/lib/python3.5/site-packages/flask/app.py", line 2000, in __call__
    return self.wsgi_app(environ, start_response)
  File "/home/alexis/dq/lib/python3.5/site-packages/flask/app.py", line 1991, in wsgi_app
    response = self.make_response(self.handle_exception(e))
  File "/home/alexis/dq/lib/python3.5/site-packages/flask/app.py", line 1567, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/home/alexis/dq/lib/python3.5/site-packages/flask/_compat.py", line 33, in reraise
    raise value
  File "/home/alexis/dq/lib/python3.5/site-packages/flask/app.py", line 1988, in wsgi_app
    response = self.full_dispatch_request()
  File "/home/alexis/dq/lib/python3.5/site-packages/flask/app.py", line 1641, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/home/alexis/dq/lib/python3.5/site-packages/flask/app.py", line 1544, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/home/alexis/dq/lib/python3.5/site-packages/flask/_compat.py", line 33, in reraise
    raise value
  File "/home/alexis/dq/lib/python3.5/site-packages/flask/app.py", line 1639, in full_dispatch_request
    rv = self.dispatch_request()
  File "/home/alexis/dq/lib/python3.5/site-packages/flask/app.py", line 1625, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/home/alexis/app.py", line 19, in hello_world
    get_jdbc_connection()
  File "/home/alexis/app.py", line 12, in get_jdbc_connection
    '/home/alexis/teradataDriverJdbc.jar')
  File "/home/alexis/dq/lib/python3.5/site-packages/jaydebeapi/__init__.py", line 381, in connect
    jconn = _jdbc_connect(jclassname, url, driver_args, jars, libs)
  File "/home/alexis/dq/lib/python3.5/site-packages/jaydebeapi/__init__.py", line 199, in _jdbc_connect_jpype
    return jpype.java.sql.DriverManager.getConnection(url, *dargs)
jpype._jexception.java.sql.SQLExceptionPyRaisable: java.sql.SQLException: No suitable driver found for jdbc:teradata://edw-dev.company.org
< p > 备注: 我还在Github项目上创建了一个问题:https://github.com/baztian/jaydebeapi/issues/66

编辑: 在baztian的建议下,我已在jPype Github项目上提出了这个问题:https://github.com/originell/jpype/issues/290

2个回答

7
一个可以解决你问题的变通方法如下所示:
   def get_jdbc_connection():
        import jpype
        if jpype.isJVMStarted() and not jpype.isThreadAttachedToJVM():
            jpype.attachThreadToJVM()
            jpype.java.lang.Thread.currentThread().setContextClassLoader(jpype.java.lang.ClassLoader.getSystemClassLoader())
        connection = jaydebeapi.connect(
            'com.teradata.jdbc.TeraDriver',
            'jdbc:teradata://edw-dev.company.org',
            {'user': 'LOGIN', 'password': 'PASSWORD', 'tmode': 'TERA', 'charset': 'UTF8'},
            '/home/alexis/teradataDriverJdbc.jar')
        return connection

当我需要重新连接时,这对我起作用了,尽管我不清楚为什么。 - slaw
我在上述实施之后仍然面临以下问题:python3.8/site-packages/_jpype.cpython-38-x86_64-linux-gnu.so已在另一个类加载器中加载 - undefined

2
这可能是一个jpype问题。Jpype是JayDeBeApi的基础。在github上有一些开放的jpype问题。请确保您使用的是最新版本的jpype。否则,您必须为jaydebeapi提供PR或希望有人为您修复它。 还要考虑与JayDeBeApi一起使用Jython。 编辑:还要考虑使用专用的python信号量来封装使用JayDeBeApi访问模块的访问。

我确认我正在使用目前最新版本的JPype1,即0.6.2。您所说的使用Jython是什么意思? - Alexis.Rolland
JayDeBeApi可以与cPython或Jython一起使用。Jython是Java实现的Python,它具有使用Java代码的完美能力。这样,JayDeBeApi就可以避免使用jpype,尤其是在多线程情况下,jpype仍然不够成熟。据我所知,Jython目前只实现了Python 2.7。 - bastian
我遇到了这个问题,但只有在直接运行Python时才会出现 - 通过笔记本运行不会出现这样的错误。可能是什么问题? - diman82

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接