cx_oracle rowfactory,cx_oracle的一些使用技巧 - I code it

工作中的数据库采用oracle。访问oracle数据库一般都采用cx_oracle包来完成,API很清晰,操作效率也比较高,而且oracle官方好像对cx_oracle也非常支持,提供了丰富的文档。这里讨论一些使用技巧,作为记录,可能对你也有用。

我最近用python写了一个小工具,这个工具根据客户端的请求查询数据库,并将结果集以json的方式返回。请求的格式如下:

1: {2: fields : [3: {name : "project_id", type : "string"},4: {name : "project_name", type : "string"}5: ],6:7: sql : "select t.project_id, t.project_name from dp_project t"8: }

即,客户端描述自己想要的元数据信息(字段名称,字段类型),以及SQL语句,服务器端根据此信息查询数据库,并将返回组织成客户端在fields中描述的那样。

cx_oracle默认从cursor中fetch出来的数据是一个元组,按照SQL中的顺序组织,但是我希望返回的是一个字典结构,这个可以通过设置cursor的rowfactory属性来实现,定义一个rowfactory的回调函数:

1: def makedict(self, cursor):2: cols = [d[0] for d in cursor.description]3:4: def createrow(*args):5: return dict(zip(cols, args))6:7: return createrow

这个函数返回一个函数:createrow。可能有点绕口,仔细想想就清晰了。cursor中带有足够的信息来生成这个字典,如cursor的description的值为:

1: [2: ('PROJECT_ID', , 40, 40, 0, 0, 0),3: ('PROJECT_NAME', , 50, 50, 0, 0, 1)4: ]

我们需要的是cursor.description的第一列,zip函数将cols和默认的那个元组合成为一个新的元组,再用dict转换为一个新的字典对象返回。

然后将这个返回函数的函数注册给cursor的rowfactory即可:

1: cursor.rowfactory = self.makedict(cursor)

这样,我们使用cursor.fetchall/fetchone的时候,取出来的就成为一个字典对象,很方便将其序列化为json格式返回。

另一个技巧是关于将查询到的结果中,字符串类型的字段转换为unicode,数值类型的不做处理:

1: def outtypehandler(self, cursor, name, dtype, size, p, s):2: if dtype in (oracle.STRING, oracle.FIXED_CHAR):3: return cursor.var(unicode, size, cursor.arraysize)

将connection对象的outputtypehandler注册为此函数即可:

1: connection = oracle.connect(self.constr)2: connection.outputtypehandler = self.outtypehandler

通用查询的这个小工具还在开发中,等完成了再整理一下。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值