Python连接GBase 8s数据库(通过DBAPI2)

本文介绍了如何利用Python的JPype库和DBAPI2.0规范来通过JDBC连接GBase8s数据库。首先,我们展示了如何安装JPype、查看DBAPI2的特性,然后建立数据库连接、创建游标并执行SQL操作。在多线程环境中,需要注意线程安全问题。最后,文章演示了不同类型数据的插入和获取,并展示了返回的数据类型。整个过程强调了JPype在非自动提交模式下操作数据库的注意事项和事务提交的重要性。
摘要由CSDN通过智能技术生成

Python中为了规范数据库访问的一致性,定义了DBAPI2.0,详情见PEP-0249
依据此API规范,JPype的DBAPI2模块进行了很好的实现。
JPype的DBAPI2是通过访问JDBC来实现DBAPI2.0接口,所以可以通过JDBC连接的数据库,它都能连接。
(JPype 也可以用于直接访问 JDBC,见Python连接GBase 8s数据库(通过JDBC)

下面我们以GBase 8s数据库为例来试用下此模块

安装JPype

pip install jpype1

导入dbapi2模块

from jpype import dbapi2

查看API级别、线程安全级别、参数样式

这三个全局参数是接口规范中要求必须定义的,方便使用者了解实现模块的情况

print('apilevel: ', dbapi2.apilevel)
print('threadsafety: ', dbapi2.threadsafety)
print('paramstyle: ', dbapi2.paramstyle)

输出结果

apilevel:  2.0
threadsafety:  2
paramstyle:  qmark

具体含义见下图PEP-0249的说明
在这里插入图片描述

建立数据库连接

import jpype

# 建立连接前需要先启动JVM
jpype.addClassPath('gbasedbtjdbc_3.4.0_2_ca1174.jar')
jpype.startJVM()

# 创建数据库连接
conn = dbapi2.connect(
    dsn='jdbc:gbasedbt-sqli://192.168.1.2:9001/testdb:GBASEDBTSERVER=gbaseserver1;NEWCODESET=UTF8,cp1252,819;DB_LOCALE=zh_CN.utf8;CLIENT_LOCALE=zh_CN.utf8;DBDATE=Y4MD-;',
    driver='com.gbasedbt.jdbc.Driver',
    driver_args={'user': 'gbasedbt', 'password': '111111'}
)

创建游标执行SQL

# 创建游标
cur = conn.cursor()
cur.execute("create table test_t1(a int, b varchar(100))")
cur.execute("insert into test_t1 values(?, ?)", (1, 'gbase8s'))
cur.execute("select * from test_t1")
for row in cur:
    for col in row:
        print(col, type(col))
cur.close()
conn.close()

输出结果

1 <java class 'JInt'>
gbase8s <class 'str'>

注意,dbapi2中采样非自动提交模式,所以上边的代码在运行完成之后,数据库中并没有建表插数据,需要commit之后才可以,如下

# 提交事务
conn.commit()

可以按照如下方式将当前连接修改为自动提交模式

conn._jcx.setAutoCommit(True)

在多线程中使用游标

连接GBase8s数据库时,当游标和连接对象不在同一个线程时,报错

from threading import Thread


def cursor_in_thread(conn_input):
    # 传入connection对象,在线程中创建游标并执行sql
    cur = conn_input.cursor()
    cur.execute("insert into test_t1 values(?, ?)", (1, 'gbase8s'))


t = Thread(target=cursor_in_thread, args=(conn,))
t.start()
t.join()

报错如下:

java.lang.java.lang.ExceptionInInitializerError: java.lang.ExceptionInInitializerError

解决办法:

def cursor_in_thread(conn_input):
    # 传入connection对象,在线程中创建游标并执行sql
    if not jpype.isThreadAttachedToJVM():
        jpype.java.lang.Thread.attach()
        jpype.java.lang.Thread.currentThread().setContextClassLoader(jpype.java.lang.ClassLoader.getSystemClassLoader())
    cur = conn_input.cursor()
    cur.execute("insert into test_t1 values(?, ?)", (1, 'gbase8s'))

数据类型测试

    tables = ['t_byte', 't_text', 't_blob', 't_clob', 't_date', 't_timestamp', ]
    cur.execute('insert into t_byte values(?)', ('中国'.encode('utf8'),))
    cur.execute('insert into t_text values(?)', ('中国'.encode('utf8'),))
    cur.execute('insert into t_blob values(?)', ('中国'.encode('utf8'),))
    cur.execute('insert into t_clob values(?)', ('中国'.encode('utf8'),))
    cur.execute('insert into t_date values(?)', ('2022-06-10',))
    cur.execute('insert into t_timestamp values(?)', ('2022-06-10 12:59:59',))
    for table in tables:
        cur.execute('select * from {}'.format(table))
        row = cur.fetchone()
        col = row[0]
        print('{},对应python的:'.format(table), type(col))

输出结果

t_byte,对应python的: <class 'bytes'>
t_text,对应python的: <class 'str'>
t_blob,对应python的: <class 'bytes'>
t_clob,对应python的: <class 'str'>
t_date,对应python的: <class 'datetime.date'>
t_timestamp,对应python的: <class 'datetime.datetime'>
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值