cx-Oracle读取LOB类型数据
什么是LOB类型数据
在ORACLE数据库中,LOB(Large Objects(大对象))是用来存储大量的二进制和文本数据的一种数据类型。在 Oracle8i 中开始提供 LOB 字段,在 Oracle10g 前最多只能存储 4G 数据,从 Oracle10g 开始,可以存储 8-128T 的数据,取决于你的数据库的块大小。
LOB又分为两种类型:
内部LOB类型:将数据以字节流的形式存储在数据库的内部。因而,内部LOB的许多操作都可以参与事务,也可以像处理普通数据一样对其进行备份和恢复操作。如:
BLOB:二进制大对象。定义一个 BLOB 变量,用于存储大量的二进制数据(如图像、视频、音频等),该二进制大对象存储于数据库中。
CLOB:字符型大对象(单字节字符数据)。定义一个 CLOB 变量,用于存储超长的文本数据,该字符型大对象存储于数据库中。
NCLOB:字符型大对象(多字节国家字符数据)。定义一个 NCLOB 变量,用于存储超长的文本数据,该字符型大对象存储于数据库中。
外部LOB类型:在数据库内仅存储数据在操作系统中的位置信息,而数据的实体以外部文件的形式存在于操作系统的文件系统中。因而,该类型所表示的数据是只读的,不参与事务。如:
BFILE:二进制文件。定义一个 BFILE 变量,它指向操作系统的一个文件,Oracle 会将其视为二进制数据进行处理。
以前内容转载自:Oracle - LOB(大对象数据类型),欲详细了解请移步。
cx_Oracle.LOB类型数据如何查看(读取)
日前从oracle查询数据时,本以为能正常返回需要的字符串数据,结果却返回了一个cx_Oracle.LOB object,这才第一次知道有这种类型。
找了一通资料之后发现cx_Oracle.LOB object有个read方法,我们只要先遍历cx_Oracle.LOB object,然后对每个元素使用read即可正常查看字符类型的原数据。
Python读写Oracle的BLOB类型
这应该算是我遇到的难题之一了。表结构是这样的:
CREATE TABLE aurora(
date_forecast VARCHAR2(10),
filename VARCHAR2(24),
content BLOB
);
- BLOB写操作
现在我有3个python的数据,分别是:
date_forecast = ‘2011-06-29’
filename = ‘aurora.jpg’’
file = open(‘aurora.jpg’, ‘rb’)’
content = fp.read()
fp.close()
网上的资料说,插入包含blob的记录,需要先插入空的blob对象,然后再update该记录——这意味着,一次INSERT操作,至少要访问3次数据库。但是,这里面有个问题无法解决:python如何给Oracle的blob对象赋值?仔细阅读Oracle的文档,发现在SQL语句中,可以使用冒号(:)来定义变量,而cx_Oracle模块中也的确有cx_Oracle.BLOB对象。至此,可以整理出这样的一个思路:
sqlStr = “INSERT INTO aurora (date_forecast, filename, content) VALUES (’%s’, ‘%s’, :blobData)” % (date_forecast,filename)
请注意blobData前边的冒号,是定义了一个叫做blobData的Oracle变量。然后,
cursor.setinputsizes(blobData=cx_Oracle.BLOB)
将blobData变量定义为cx_Oracle.BLOB的实例,终于让python和Oracle握手了。接下来,就是水到渠成的事情了,
cursor.execute(sqlStr, {‘blobData’:content})
cursor.execute(‘commit’)
2. BLOB读操作
sqlStr = "SELECT date_forecast, filename, content FROM (SELECT date_forecast, filename, content FROM aurora ORDER BY date_forecast DESC) where ROWNUM < 2 "
cursor.execute(sqlStr)
result = cursor.fetchall()
此时,result[0][2]就是BLOB对象,python如何操作它呢?
print type(result[0][2])
才想起来它是一个cx_Oracle.BLOB对象,呵呵,继续:
print dir(cx_Oracle.BLOB)
发现cx_Oracle.BLOB有一个read方法,
print type(result[0][2].read())
终于看到熟悉的str类型,搞定!
file = open(‘aurora.jpg’, “wb”)
file.write(result[0][2].read())
file.close()
oracle数据库中blob数据读取
blob b’xxxxxxx’
clob ‘xxxxxxxx’
import cx_Oracle
import datetime
connection = cx_Oracle.connect(user=“dhcc01”, password=“dhcc010803”,dsn=“172.28.30.6:1521/orcl”)
connection = cx_Oracle.connect(user=“test”, password=“rootrootrootroot”,dsn=“10.10.122.84:1521/orcl”)
connection = cx_Oracle.connect(user=“pretest03”, password=“pretest031217”,dsn=“172.20.20.8:1521/orcl”)
basePath=“C:\Users\MyComputer\Desktop\xxxxx\”
db2_filename=basePath+“db2_output.sql”
mysql_filename=basePath+“mysql_output.sql”
oracle_filename=basePath+“oracle_output.sql”
sqlserver_filename=basePath+“sqlserver_output.sql”
db2_file=open(db2_filename,‘w’)
mysql_file=open(mysql_filename,‘w’)
oracle_file=open(oracle_filename,‘w’)
sqlserver_file=open(sqlserver_filename,‘w’)
cursor = connection.cursor()
#检索库中所有表
cursor.execute(""“select table_name from user_tables “””)
tablenames=cursor.fetchall()
for tmp_tablename in tablenames:
#检索表列的信息
v_tablename=tmp_tablename[0]
param={‘tabname’:v_tablename}
cursor.execute(""“select table_name,column_name,data_type from user_tab_columns where table_name= :tabname order by column_id asc”"",param )
tablecolumns=cursor.fetchall()
#print(tablecolumns)
insert_str=‘insert into ‘+v_tablename+’(’
#检索列名,生成列语句,以逗号分隔
for column in tablecolumns:
insert_str=insert_str+column[1]+’,’
#删除多余的逗号
insert_len=len(insert_str)
insert_str=insert_str[0:insert_len-1]
insert_str+=’) values’
#print(insert_str)
#多少行提交一次
commit_count=100
#提交行计数器
commit_counter=0
cursor.execute("""select * from """+v_tablename )
#检索每行数据
for row in cursor:
db2_valuestring='('
mysql_valuestring='('
oracle_valuestring='('
sqlserver_valuestring='('
#检索每行每列的数据,构建values语句
for column in row:
if isinstance(column,datetime.datetime)==True:
db2_valuestring=db2_valuestring+"timestamp('"+column.strftime("%Y-%m-%d %H:%M:%S")+"'),"
oracle_valuestring=oracle_valuestring+"to_date('"+column.strftime("%Y-%m-%d %H:%M:%S")+"','yyyy/mm/dd hh24:mi:ss'),"
mysql_valuestring=mysql_valuestring+"'"+column.strftime("%Y-%m-%d %H:%M:%S")+"',"
sqlserver_valuestring=sqlserver_valuestring+"'"+column.strftime("%Y-%m-%d %H:%M:%S")+"',"
elif isinstance(column,int)==True:
db2_valuestring=db2_valuestring+str(column)+","
mysql_valuestring=mysql_valuestring+str(column)+","
oracle_valuestring=oracle_valuestring+str(column)+","
sqlserver_valuestring=sqlserver_valuestring+str(column)+","
elif isinstance(column,float)==True:
db2_valuestring=db2_valuestring+str(column)+","
mysql_valuestring=mysql_valuestring+str(column)+","
oracle_valuestring=oracle_valuestring+str(column)+","
sqlserver_valuestring=sqlserver_valuestring+str(column)+","
elif isinstance(column,str)==True:
db2_valuestring=db2_valuestring+"'"+str(column)+"'"+","
mysql_valuestring=mysql_valuestring+"'"+str(column)+"'"+","
oracle_valuestring=oracle_valuestring+"'"+str(column)+"'"+","
sqlserver_valuestring=sqlserver_valuestring+"'"+str(column)+"'"+","
elif column is None:
db2_valuestring=db2_valuestring+"NULL"+","
mysql_valuestring=mysql_valuestring+"NULL"+","
oracle_valuestring=oracle_valuestring+"NULL"+","
sqlserver_valuestring=sqlserver_valuestring+"NULL"+","
#lob类型处理好,blob只能用read方法,clob可直接使用
elif isinstance(column,cx_Oracle.LOB):
# print(v_tablename)
# print(type(column))
temp_lob=column.read()
# print(temp)
db2_valuestring=db2_valuestring+"'"+str(temp_lob)+"',"
mysql_valuestring=mysql_valuestring+"'"+str(temp_lob)+"',"
oracle_valuestring=oracle_valuestring+"'"+str(temp_lob)+"',"
sqlserver_valuestring=sqlserver_valuestring+"'"+str(temp_lob)+"',"
else:
# print(v_tablename)
# print(type(column))
db2_valuestring=db2_valuestring+"'"+str(column)+"'"+","
mysql_valuestring=mysql_valuestring+"'"+str(column)+"'"+","
oracle_valuestring=oracle_valuestring+"'"+str(column)+"'"+","
sqlserver_valuestring=sqlserver_valuestring+"'"+str(column)+"'"+","
#删除多余的逗号
db2_value_len=len(db2_valuestring)
db2_valuestring=db2_valuestring[0:db2_value_len-1]
db2_valuestring=db2_valuestring+");\n"
db2_combinestring=insert_str+db2_valuestring
mysql_value_len=len(mysql_valuestring)
mysql_valuestring=mysql_valuestring[0:mysql_value_len-1]
mysql_valuestring=mysql_valuestring+");\n"
mysql_combinestring=insert_str+mysql_valuestring
oracle_value_len=len(oracle_valuestring)
oracle_valuestring=oracle_valuestring[0:oracle_value_len-1]
oracle_valuestring=oracle_valuestring+");\n"
oracle_combinestring=insert_str+oracle_valuestring
sqlserver_value_len=len(sqlserver_valuestring)
sqlserver_valuestring=sqlserver_valuestring[0:sqlserver_value_len-1]
sqlserver_valuestring=sqlserver_valuestring+");\n"
sqlserver_combinestring=insert_str+sqlserver_valuestring
db2_file.writelines(db2_combinestring)
mysql_file.writelines(mysql_combinestring)
oracle_file.writelines(oracle_combinestring)
sqlserver_file.writelines(sqlserver_combinestring)
#行循环中每行加1,指定commit_count添加commit命令
commit_counter+=1
if commit_counter%commit_count==0:
db2_file.writelines("commit;\n")
mysql_file.writelines("commit;\n")
oracle_file.writelines("commit;\n")
#每张表结束再提交一次
#表如果有空行,会出现多个commit,可以不用处理
db2_file.writelines("commit;\n")
mysql_file.writelines("commit;\n")
oracle_file.writelines("commit;\n")
db2_file.close()
mysql_file.close()
oracle_file.close()
sqlserver_file.close()




