The problem was that some characters e.g. £ and € would cause the file.write() method to error due to non 'ascii' characters. But the error was not consistent, i.e. my code worked exporting data from some tables, but not others !?
Code 1:
import odbc
sql = "%s\n"
dsn = 'DRIVER=SQL Server;SERVER=SOPSSQL;DATABASE=Test'
cnn = odbc.odbc(dsn)
cur = cnn.cursor()
cur.execute("SELECT Field1, Field2, Field3 FROM dbo.Table")
rst = cur.fetchall()
fo = open(r"text1.txt", 'wb')
for row in rst:
fo.write(sql % ','.join(row))
fo.close()
cnn.close
So why did this not work for all data from all tables?
I eventually tracked down that the error only occurred when the field was a VARCHAR(n). I then noticed that VARCHAR(n) fields were being returned as UNICODE while CHAR(n) were not.
Python happily wrote the CHAR(N) text to the file with £ and € in it, no problem, while any £ or € in the Unicode would cause it to error.
Below is my function to change the encoding of the UNICODE elements of the tuple "row" in to something Python would write to a file correctly.
Code 2 (New function, plus changed row only):
def enCode(item):
if type(item) == unicode: return item.encode('cp1252').strip()
else: return item
...
fo.write(sql % ','.join(map(enCode, row)))
...
If someone knows a better way i.e. a built in Python function, then please let me know.
import odbc
sql = "%s\n"
dsn = 'DRIVER=SQL Server;SERVER=SOPSSQL;DATABASE=Test'
cnn = odbc.odbc(dsn)
cur = cnn.cursor()
cur.execute("SELECT Field1, Field2, Field3 FROM dbo.Table")
rst = cur.fetchall()
fo = open(r"text1.txt", 'wb')
for row in rst:
fo.write(sql % ','.join(row))
fo.close()
cnn.close
So why did this not work for all data from all tables?
I eventually tracked down that the error only occurred when the field was a VARCHAR(n). I then noticed that VARCHAR(n) fields were being returned as UNICODE while CHAR(n) were not.
Python happily wrote the CHAR(N) text to the file with £ and € in it, no problem, while any £ or € in the Unicode would cause it to error.
Below is my function to change the encoding of the UNICODE elements of the tuple "row" in to something Python would write to a file correctly.
Code 2 (New function, plus changed row only):
def enCode(item):
if type(item) == unicode: return item.encode('cp1252').strip()
else: return item
...
fo.write(sql % ','.join(map(enCode, row)))
...
If someone knows a better way i.e. a built in Python function, then please let me know.
No comments:
Post a Comment