[cx-oracle-users] blob streaming, possible improvement
Brought to you by:
atuining
From: Joram A. <jor...@gm...> - 2012-08-31 07:25:11
|
Hello, I had to upload 20GB of documents from an ftp site, to a table with a BLOB column. In order to do this in a streaming fashion I had to write a little helper class for the BLOB stream. (see code example below) It would be handy if the BLOB write function did not need an offset parameter. So writing without offset specified moves it automatically along ( offset += len(data) ) and the BLOB object remembers the last written offset (as the instantiated Helper class in my example) I think that is more in sync with the other file-type like write functions (see also StringIO as an example) Hopefully this is easy to integrate in cx_Oracle. Thanks in advance Joram import cx_Oracle import ftplib dsn = "scott/tiger" connection = cx_Oracle.connect(dsn) cursor = connection.cursor() ftp = ftplib.FTP() ftp.connect("host", 21) ftp.login("user", "passwd") class Helper(object): def __init__(self, writer): print("initializing helper with writer {w}".format(w=writer)) self.writer = writer self.offset = 1 def write(self, data, offset=None): if not offset: offset = self.offset print("calling write on helper with {len} bytes of date, current offset {offset}".format(len=len(data), offset=self.offset)) self.writer.write(data, offset) self.offset += len(data) try: attachment_id = 1 file_name = "bigfile.txt" bigFileVar = cursor.var(cx_Oracle.BLOB) cursor.execute("""UPDATE ta_cs_attachments SET file_data = empty_blob() , upload_processed_flg = 'Y' WHERE attachment_id = :attachment_id RETURNING file_data INTO :file_data""" , {'attachment_id' : attachment_id, "file_data": bigFileVar}) blob = bigFileVar.getvalue() helper = Helper(blob) ftp.retrbinary("RETR " + file_name, helper.write, 65536) connection.commit() except cx_Oracle.DatabaseError, exc: error, = exc.args print(error) except ftplib.error_temp, msg: print("error in uploading, {e}".format(e=msg)) cursor.close() connection.close() ftp.quit() |