Oracle python cx_Oracle 入门

〇、使用数据库驻留连接池
数据库驻留连接池是 Oracle Database 11g 的一个新特性。它对 Web 应用程序常用的短期脚本非常有用。它允许随着 Web 站点吞吐量的增长对连接数量进行扩充。它还支持多台计算机上的多个 Apache 进程共享一个小规模的数据库服务器进程池。没有 DRCP,Python 连接必须启动和终止一个服务器进程。
所有脚本都可使用来自服务器池的数据库服务器,不再需要时将退回服务器。

一、Oracle 简单查询
查询的基础始终是相同的:
1. 分析要执行的语句。 
2. 绑定数据值(可选)。 
3. 执行语句。 
4. 从数据库中获取结果。

 

import cx_Oracle
con = cx_Oracle.connect('pythonhol/welcome@127.0.0.1/orcl')
cur = con.cursor()  #cursor() 方法打开语句要使用的游标。
cur.execute('select * from departments order by department_id') #execute() 方法分析并执行语句。
for result in cur:  #循环从游标获取每一行并输出该行。
    print result
cur.close()
con.close()         

 


二、Oracle 获取数据
从 Oracle 数据库中获取数据的方式有多种
1)使用cursor.fetchone()方法

 

import cx_Oracle
con = cx_Oracle.connect('pythonhol/welcome@127.0.01/orcl')
cur = con.cursor()
cur.execute('select * from departments order by department_id')
               
row = cur.fetchone()  # fetchone() 方法只返回一行作为一个字节组
print row
row = cur.fetchone()  # 多次调用该方法后,返回连续的多行
print row
            
cur.close()
con.close()

 


执行完毕后,两次 fetchone() 调用输出两条记录

2)使用cursor.fetchmany()方法

 

import cx_Oracle
con = cx_Oracle.connect('pythonhol/welcome@127.0.0.1/orcl')
cur = con.cursor()
cur.execute('select * from departments order by department_id')
               
res = cur.fetchmany(numRows=3)  #返回一个字节组列表,numRows 参数指定应返回三行
print res

cur.close()
con.close()

 


执行完毕后,以字节组列表形式返回了表的头三行

3)使用cursor.fetchall()方法

 

import cx_Oracle
con = cx_Oracle.connect('pythonhol/welcome@127.0.0.1/orcl')
cur = con.cursor()
cur.execute('select * from departments order by department_id')
               
res = cur.fetchall()  #返回所有行
print res             #输出是一个字节组列表,每个字节组包含一行的数据

for r in res:         #每个字节组分别输出,选择使用哪种获取方法主要取决于您希望如何处理返回的数据
    print r
   
cur.close()
con.close()

 


三、提高查询性能
通过增加每批从 Oracle 返回到 Python 程序的行数来提高查询性能的方法。

 

import time
import cx_Oracle
con = cx_Oracle.connect('pythonhol/welcome@127.0.0.1/orcl')
start = time.time()
cur = con.cursor()
cur.arraysize =100   #每次从数据库向 Python 的缓存返回 100 条记录
cur.execute('select * from bigtab')
res = cur.fetchall()
# print res  # uncomment to display the query results
elapsed = (time.time() - start)
print elapsed, " seconds"
cur.close()
con.close()

 


cursor.arraysize 合理设置,可以减少对数据库的“往返”次数,通常还会降低网络负载并减少数据库服务器上下文切换次数
从数据库请求更多的数据之前,fetchone()、fetchmany()、甚至 fetchall() 方法都将从缓存读取数据。
要增加 arraysize,需要在时间/空间方面进行权衡。arraysizes 越大,Python 中用于缓存记录需要的内存也越大。 

四、使用绑定变量
绑定变量允许您使用新值重新执行语句,避免了重新分析语句的开销。绑定变量提高了代码可重用性,降低了 SQL 注入攻击的风险。

 

import cx_Oracle
con = cx_Oracle.connect('pythonhol/welcome@127.0.0.1/orcl')
cur = con.cursor()
cur.prepare('select * from departments where department_id = :id')  #绑定变量前的准备
cur.execute(None, {'id': 210})  #第一次绑定变量执行,通过 python 字典的方式进行传参
res = cur.fetchall()
print res
cur.execute(None, {'id': 110})  #第二次绑定变量执行
res = cur.fetchall()
print res
cur.close()
con.close()  

 


该语句包含一个绑定变量“:id”。该语句只准备了一次,但针对 WHERE 子句的不同值执行了两次。
因为 prepare() 方法已经对该语句进行了设置,因此对 execute() 使用特殊符号“None”代替该语句的文本参数。

cx_Oracle 驱动程序支持 INSERT 语句的数组绑定,这样可以大大提高单行插入的性能。

 

import cx_Oracle
con = cx_Oracle.connect('pythonhol/welcome@127.0.0.1/orcl')
rows =[(1,"First"),
         (2,"Second"),
         (3,"Third"),
         (4,"Fourth"),
         (5,"Fifth"),
         (6,"Sixth"),
         (7,"Seventh")]
cur = con.cursor()
cur.bindarraysize =7       # bindarraysize 设置为 7,意味着一次就插入全部七行
cur.setinputsizes(int, 20)  # setinputsizes() 调用描述了列的情况,第一列是整数。第二列最多为 20 个字节
cur.executemany("insert into mytab(id, data) values (:1, :2)", rows)  #调用插入全部七行。
#con.commit()               #commit() 调用被注释掉了,因此不会真正被插入数据库中
# Now query the results back
cur2 = con.cursor()         #当执行第二次查询的时候,新建了一个游标
cur2.execute('select * from mytab')
res = cur2.fetchall()
print res
cur.close()
cur2.close()
con.close()

 


五、创建事务
在 Oracle 数据库中操作数据(插入、更新或删除数据)时,更改的数据或新数据在提交至数据库前仅在数据库会话中可用。更改的数据提交至数据库,然后可供其他用户和会话使用。这是一个数据库事务。

 

import cx_Oracle
con = cx_Oracle.connect('pythonhol/welcome@127.0.0.1/orcl')
rows =[(1,"First"),
         (2,"Second"),
         (3,"Third"),
         (4,"Fourth"),
         (5,"Fifth"),
         (6,"Sixth"),
         (7,"Seventh")]
cur = con.cursor()
cur.bindarraysize =7
cur.setinputsizes(int,20)
cur.executemany("insert into mytab(id, data) values (:1, :2)", rows)
con.commit()                    #commit() 是针对连接执行,而非针对游标,因此前面使用的是数据库连接的对象
# Now query the results back
cur2 = con.cursor()
cur2.execute('select * from mytab')
res = cur2.fetchall()
print res
cur.close()
cur2.close()
con.close()

 


如果需要在脚本中启动回滚,则可使用 con.rollback() 方法。

六、使用 PL/SQL 存储函数和过程
PL/SQL 是 Oracle 对 SQL 的过程语言扩展。PL/SQL 过程和函数在数据库中存储和运行。使用 PL/SQL 允许所有数据库应用程序重用逻辑,无论应用程序以何种方式访问数据库。许多与数据相关的操作在 PL/SQL 中的执行速度比将数据提取到一个程序中(例如,Python)然后再进行处理的速度快。Oracle 还支持 Java 存储过程。

 

import cx_Oracle
con = cx_Oracle.connect('pythonhol/welcome@127.0.0.1/orcl')
cur = con.cursor()
res = cur.callfunc('myfunc', cx_Oracle.NUMBER,('abc',2))
print res
cur.close()
con.close()           

 

    
该脚本使用 callfunc() 执行此函数。常量 cx_oracle.NUMBER 指示返回值是数字。PL/SQL 函数的两个参数作为一个字节组传输并绑定到该函数的参数。
要调用 PL/SQL 过程,使用 cur.callproc() 方法。


七、连续查询通知
连续查询通知(也称为数据库更改通知)允许应用程序在表更改时(例如,向表中插入行)接收通知。在许多情况下这一功能非常有用,包括中间层缓存无效的情况。缓存可能会容纳一些与表数据有依赖关系的值。如果表发生更改,缓存的值也必须按照新信息进行更新。

 

One Response


    还没有评论!
1  

Leave your comment

请留下您的姓名(*)

请输入正确的邮箱地址(*)

请输入你的评论(*)


感谢开源 © 2016. All rights reserved.&3Q Open Source&^_^赣ICP备15012863号-1^_^
乐于分享共同进步 KreativeThemes