Ik heb een oplossing gemaakt met
- Oracle Database 12c met Database Characterset AL32UTF8 (verplicht om Unicode op te slaan !!)
- SCOTT-schema
- Oracle Instant-client 12.2 met ODBC-pakket (kan gratis worden gedownload van Oracle)
- Oracle SQL Developer (tool die Unicode-tekens kan invoeren en verbinding kan maken via Java/JDBC)
- Python 3.8
De onderstaande Python-code is naar mijn mening zelfverklarend - alleen IP, PORT en SERVICE in de verbindingsreeks hoeven te worden gewijzigd. Om de Unicode-tekens op shell/cmd te bekijken, moet u de omgevingsvariabele instellen
PYTHONIOENCODING=UTF-8
Helaas werkt dit niet op Eclipse IDE met PyDEV, dus ik gebruikte try-behalve om lopende code te krijgen. Heeft me een paar uur hoofdpijn bezorgd...
#
# Safe python file as UTF-8 - otherwise you get no UTF-8 output !!!!
#
# Unix:
# export PYTHONIOENCODING=UTF-8
#
# Windows:
# set PYTHONIOENCODING=UTF-8
#
# Eclipse/PyDev:
# create for run/debug environment variable
# PYTHONIOENCODING=UTF-8
#
# ODBC:
# Oracle Instantclient 12.2 + ODBC package
#
# DB:
# Oracle RDBMS 12.2 with Database Characterset AL32UTF8 to allow Unicode
#
# SQL Tool to Execute SQL (JDBC)
# Oracle SQL Developer
#
# SQL
# connect scott/tiger
# create table polish(col1 varchar2(50));
# insert into polish(col1) values('SQLD ł ń');
# commit;
#
#
import pyodbc
bl = " "
UTF8 = "UTF-8"
strict = "Strict"
s1 = "Test "+UTF8
print(s1)
s1 = chr(322) + bl + chr(324)
m = bytes(s1,UTF8)
print(m)
try:
print(m.decode(UTF8,strict))
except:
pass
print()
print("Test ODBC and " + UTF8)
print("Test ODBC and " + UTF8)
cs = "DRIVER={DRIVERNAME};UID={USERID};PWD={PASSWD};DBQ={IP_OR_HOSTNAME}:{PORT}/{SERVICE_OR_SID};"
csfill = cs.format(DRIVERNAME="Oracle in instantclient_12_2",
IP_OR_HOSTNAME="111.222.33.44",
PORT=12102,
SERVICE_OR_SID="DB1212UTF",
USERID="SCOTT",
PASSWD="tiger")
print(csfill)
cn = pyodbc.connect(csfill)
cursor = cn.cursor()
# Do the insert - can be done using normal parameters and Unicode strings...
cursor.execute("insert into Polish(COL1) values ( ? )", u"Python ł ń")
# perform commit if want to inspect in SQL Developer
# cursor.commit()
cursor = cn.cursor()
# We need to cast COL1 so that unicode is shipped as ' \xxxx'
# unfortunatly Unicode deos not work directly
# so we use ASCIISTR() to do that...
cursor.execute('SELECT ASCIISTR(COL1)"COL1" from Polish')
rows = cursor.fetchall()
for row in rows:
s =""
x = row.COL1
y = 0
j = len(x)-1
# Parse incoming column for Oracle-Style Unicode like ' \0142'
while y <= j:
if y + 5 <= j:
# detect if oracle unicode begins with blank and slash -> ' \'
sc = x[y]+x[y+1]
if sc == " \\":
# create unicode character
c = x[y+2]+x[y+3]+x[y+4]+x[y+5]
s += bl + chr(int(c,16))
# step forward to next character
y += 5
else:
# no unicode 4 characters before end !!
s += chr(ord(x[y]))
else:
# no unicode - regular ASCII
s += chr(ord(x[y]))
y += 1
m = bytes(s,UTF8)
print(m)
try:
print(m.decode(UTF8,strict))
except:
pass
cursor.close()
cn.close()
Lopende applicatie geeft
Test UTF-8
b'\xc5\x82 \xc5\x84'
ł ń
Test ODBC and UTF-8
DRIVER=Oracle in instantclient_12_2;UID=SCOTT;PWD=tiger;DBQ=111.222.33.44:12102/DB1212UTF;
b'SQLD \xc5\x82 \xc5\x84'
SQLD ł ń
b'Python \xc5\x82 \xc5\x84'
Python ł ń