Oracle Datumsformat wird nicht in Deutsch ausgegeben

Installation und Anwendung von Datenbankschnittstellen wie SQLite, PostgreSQL, MariaDB/MySQL, der DB-API 2.0 und sonstigen Datenbanksystemen.
Antworten
chrischn
User
Beiträge: 18
Registriert: Freitag 23. September 2016, 09:35

Hallo,

ich greife über Python und dem Oracle Treiber auf eine Oracle Datenbank zu. Schreibe ich ein select auf ein Datenbankfeld im DATE Format und exportiere dieses in eine CSV Datei, dann wird das Datum in folgendem Format ausgegeben :

2016-03-11 00:00:00

Leider bekomme ich es nicht hin, dass das Datum im Deutschen Format ohne die Zeit exportiert wird.

Ich bin dann natürlich recht flott auf die NLS Variablen gestossen. Diese habe ich dann vor Ausführung meines SQLs auf die folgenden Werte gesetzt und habe diverse Versuche/Anpassungen vorgenommen :

( Nur so nebenbei: ein € Zeichen nimmt er übrigens nicht, da dann eine Fehlermeldung erscheint, dass er das Zeichen nicht kennt )

11.2.0.3.0
('NLS_LANGUAGE', 'GERMAN')
('NLS_TERRITORY', 'GERMANY')
('NLS_CURRENCY', 'EUR')
('NLS_ISO_CURRENCY', 'GERMANY')
('NLS_NUMERIC_CHARACTERS', ',.')
('NLS_CALENDAR', 'GREGORIAN')
('NLS_DATE_FORMAT', 'DD.MM.YY')
('NLS_DATE_LANGUAGE', 'GERMAN')
('NLS_CHARACTERSET', 'WE8MSWIN1252')
('NLS_SORT', 'GERMAN')
('NLS_TIME_FORMAT', 'HH24:MI:SSXFF')
('NLS_TIMESTAMP_FORMAT', 'DD.MM.RR HH24:MI:SSXFF')
('NLS_TIME_TZ_FORMAT', 'HH24:MI:SSXFF TZR')
('NLS_TIMESTAMP_TZ_FORMAT', 'DD.MM.RR HH24:MI:SSXFF TZR')
('NLS_DUAL_CURRENCY', 'EUR')
('NLS_NCHAR_CHARACTERSET', 'AL16UTF16')
('NLS_COMP', 'BINARY')
('NLS_LENGTH_SEMANTICS', 'BYTE')
('NLS_NCHAR_CONV_EXCP', 'FALSE')

Im SQL Developer funktioniert alles korrekt.

Weiß jemand einen Rat ?


Hier nochmal der Code.....

Code: Alles auswählen

import os 
import cx_Oracle
import csv
con = cx_Oracle.connect('XXXXXXXXXXXXXXXXXXX')
print(con.version)


SQL00='alter session set NLS_LANGUAGE="GERMAN"'
SQL01='alter session set NLS_TERRITORY="GERMANY"'
SQL02='alter session set NLS_CURRENCY="EUR"'
SQL03='alter session set NLS_ISO_CURRENCY="GERMANY"'
SQL04='alter session set NLS_TIME_FORMAT="dd.mm.rr"'
SQL05='alter session set NLS_TIMESTAMP_FORMAT="DD.MM.RR HH24:MI:SSXFF"'
SQL06='alter session set NLS_TIME_TZ_FORMAT="HH24:MI:SSXFF TZR"'
SQL07='alter session set NLS_TIMESTAMP_TZ_FORMAT="DD.MM.RR HH24:MI:SSXFF TZR"'
SQL08='alter session set NLS_DUAL_CURRENCY="EUR"'
SQL09='alter session set nls_date_format="DD.MM.YY"'

SQL1='SELECT  *  FROM    V$NLS_PARAMETERS'
SQL2="select * from TEST where TEST2='ABC' and nr=9509895"
 
# Network drive somewhere
filename="output.csv"
FILE=open(filename,"w");
output=csv.writer(FILE, dialect='excel',delimiter=";")
 
# You can set these in system variables but just in case you didnt
#os.putenv('ORACLE_HOME', '/oracle/product/10.2.0/db_1') 
#os.putenv('LD_LIBRARY_PATH', '/oracle/product/10.2.0/db_1/lib') 
#connection = cx_Oracle.connect('userid/password@99.999.9.99:PORT/SID')
 

cursor = con.cursor()

cursor.execute(SQL00)
cursor.execute(SQL01)
cursor.execute(SQL02)
cursor.execute(SQL03)
# cursor.execute(SQL04)
cursor.execute(SQL05)
cursor.execute(SQL06)
cursor.execute(SQL07)
cursor.execute(SQL08)
cursor.execute(SQL09)


cursor.execute(SQL2)
for row in cursor:
    print(row)
    output.writerow(row)
cursor.close()
con.close()
FILE.close()
BlackJack

@chrischn: Schau Dir mal an als welcher Typ das Datum von der Datenbank geliefert wird (`print()` und `type()`), denn ich hoffe ja das es nicht als Zeichenkette in irgendeiner Formatierung kommt, sondern als `datetime`-Objekt. Das bist Du dann auf Pythonseite dafür verantwortlich das so zu formatieren wie Du möchtest (`format()`-Funktion mit den Platzhaltern die auch für `datetime.strftime()` gelten oder eben diese Methode).
chrischn
User
Beiträge: 18
Registriert: Freitag 23. September 2016, 09:35

Hy BlackJack

wird das Datum im select direkt formatiert, funktioniert es, wie es soll:

z.B. mit select TO_CHAR(fakt_tgdat,'DD.MM.YYYY') from fa where .....

Gebe ich es mit print(raw) dann aus bekomme ich :
('11.03.2016',)

Das passt ja denke ich.

---------------------------------------------

ohne Formatierung im select, wird es wie beschrieben so ausgegeben :
2016-03-11 00:00:00

print(raw) ergibt dann folgendes: ( egal wie ich die session Variablen setze
(datetime.datetime(2016, 3, 11, 0, 0),)


für type(raw) bekomme ich jeweils kein Ergebnis


------

setzte ich die Session Variablen für das Datumsformat im SQL Developer, dann greift dies
für diese Session im SQL Developer dann auch. Generell scheint es also auch zu funktionieren.

Nur nicht mir dem oracle_cx Treiber

Gruß
Chrischn
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

@chrischn: Die Datenbank hat verschiedene Datentypen und Python kennt Datentypen. Wenn die übersetzt werden können, dann macht das die Datenbankanbindung auch, denn das ist das, was man normalerweise möchte. ein DATE-Feld in Oracle wird dann zum datetime-Objekt in Python. Diese ganze Konfiguration wird ja nur verwendet, wenn man der Datenbank sagt, sie soll bestimmte Werte als Strings interpretieren.
BlackJack

@chrischn: Jeder Wert in Python hat einen Typ und `type()` liefert auch für jeden Wert ein Ergebnis. Du hast das vielleicht nicht *ausgegeben*‽
chrischn
User
Beiträge: 18
Registriert: Freitag 23. September 2016, 09:35

Ich Dummerchen :-)

print(type(row))

Ergab dann : <class 'tuple'>

in beiden Fällen
BlackJack

@chrischn: Was in beiden Fällen nicht hilfreich gewesen wäre weil ja nicht der Typ von `row` interessiert, sondern was für einen Typ das Ergebnis in diesem Tupel hat. Was durch ``print(row)`` ja aber mittlerweile auch geklärt war, weil die `repr()`-Darstellung von `datetime`-Objekten deutlich genug ist.
chrischn
User
Beiträge: 18
Registriert: Freitag 23. September 2016, 09:35

Mein Fazit um das Thema abzuschliessen : Das Problem liegt nicht bei Oracle, sondern beim Client, d.H. beim cx_oracle Treiber bzw. python.

Daher werde ich wahrscheinlich damit leben müssen, das Datum mit char oder ähnlichem direkt im select Abfruf anzupassen:

select TO_CHAR(meindatum,'DD.MM.YYYY') from abc

Gruß
Chrischn
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

@chrischn: es ist kein Problem, sondern ganz natürlich, dass sie der Client um die Anzeige kümmert. Dass dafür ein OracleClient auf Oracle-Einstellungen zurückgreift, scheint mir nicht sehr ungewöhnlich. Aber warum sollte Python das machen? Dir steht es ja frei NLS_DATE_FORMAT auszulesen und das datetime.strftime zu übergeben.
Antworten