Python Forum

Full Version: Cursor write 3rd file empty
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Hi all,

I have this code below where from table all have values so all files generated should not be empty.

import cx_Oracle as oracledb

def output_type_handler(cursor, name, default_type, size, precision, scale):
    if default_type == oracledb.CLOB:
        return cursor.var(oracledb.LONG_STRING, arraysize=cursor.arraysize)
    if default_type == oracledb.BLOB:
        return cursor.var(oracledb.LONG_BINARY, arraysize=cursor.arraysize)

conn = oracledb.connect("/", mode=oracledb.SYSASM)
conn.outputtypehandler = output_type_handler

prev_name = None
cursor.execute("select cellname, confval from v$cell_config where conftype='CELL' order by cellname desc")
for name, val in cursor:
    if name != prev_name:
        filename = "my_file_%s.xml" %name
        print("File name is: ", filename) 
        print("XML Content for this line is: ", val) 
        f = open(filename,"w")
        prev_name = name
        f.write(val)
It generate 3 files where 1 is empty:

Output:
-rw-r--r-- 1 grid oinstall 2008 Mar 9 23:23 my_file_172.16.4.129;172.16.4.130.xml -rw-r--r-- 1 grid oinstall 2008 Mar 9 23:23 my_file_172.16.4.127;172.16.4.128.xml -rw-r--r-- 1 grid oinstall 0 Mar 9 23:23 my_file_172.16.4.125;172.16.4.126.xml
If I debug using print I can see data for all 3 lines .

Seems cursor is writing X-1 (Skeeping the latest one it tries to generate. It create file but did not write to it.)

Can anyone help on this?
Close your files.

A few comments about your code.

Are there only two possible types?
def output_type_handler(cursor, name, default_type, size, precision, scale):
    if default_type == oracledb.CLOB:
        return cursor.var(oracledb.LONG_STRING, arraysize=cursor.arraysize)
    if default_type == oracledb.BLOB:
        return cursor.var(oracledb.LONG_BINARY, arraysize=cursor.arraysize)
If so, you should write like this:
def output_type_handler(cursor, name, default_type, size, precision, scale):
    if default_type == oracledb.CLOB:
        return cursor.var(oracledb.LONG_STRING, arraysize=cursor.arraysize)
   return cursor.var(oracledb.LONG_BINARY, arraysize=cursor.arraysize)
If there are more types than CLOB and BLOB, you should raise an exception
def output_type_handler(cursor, name, default_type, size, precision, scale):
    if default_type == oracledb.CLOB:
        return cursor.var(oracledb.LONG_STRING, arraysize=cursor.arraysize)
    if default_type == oracledb.BLOB:
        return cursor.var(oracledb.LONG_BINARY, arraysize=cursor.arraysize)
    raise ValueError("Unsupported output type")
Functions should never return a value, always return a value, or throw an error if it is supposed to return something but can't. This prevents the confusing error message:
Error:
AttributeError: 'NoneType' object has no attribute xxx
Is this code supposed to prevent duplicates?
for name, val in cursor:
    if name != prev_name:
It will if the replay is sorted by name. Is that the case? Is that always the case?

And be sure to close your files.
for name, val in cursor:
    if name != prev_name:
        filename = "my_file_%s.xml" %name
        print(f"File name is: {filename}\nXML Content for this line is: {val}") 
        with open(filename, "w") as file:  # Context manager automatically closes file for you
            file.write(val)
        prev_name = name
It is showing errors like below:
>>> cursor = conn.cursor()
>>> cursor.execute("select cellname, confval from v$cell_config where conftype='CELL' order by cellname desc")
<cx_Oracle.Cursor on <cx_Oracle.Connection to user @local>>
>>> for name, val in cursor:
...     if name != prev_name:
...         filename = "my_file_%s.xml" %name
...         print(f"File name is: {filename}\nXML Content for this line is: {val}")
Error:
File "<stdin>", line 4 print(f"File name is: {filename}\nXML Content for this line is: {val}") ^ SyntaxError: invalid syntax >>> with open(filename, "w") as file: # Context manager automatically closes file for you File "<stdin>", line 1 with open(filename, "w") as file: # Context manager automatically closes file for you ^ IndentationError: unexpected indent >>> file.write(val) File "<stdin>", line 1 file.write(val) ^ IndentationError: unexpected indent >>> prev_name = name File "<stdin>", line 1 prev_name = name ^ IndentationError: unexpected indent

I'm using python 2.7. Seems it does not work with print(f) . I remove and now is working fine. tks
(Mar-10-2022, 01:42 PM)paulo79 Wrote: [ -> ]I'm using python 2.7. Seems it does not work with print(f) . I remove and now is working fine. tks

from __future__ import print_function
https://docs.python.org/3/library/__future__.html

Support since Python 2.6.0a2, but if you import the print_function, you've to change all existing code where print is used.