Serie: Einführung in den Inhalt von cx_Oracle
Bitte erstellen Sie die folgende Tabelle.
sample17.sql
create table sample17(
col_date date
, col_ts timestamp(9)
, col_tz timestamp(9) with time zone
);
Wie in 6. und 9. erläutert, Typ DATE Der entsprechende Python-Typ für ist datetime.datetime. Für den Typ DATE können Sie normal mit DB austauschen, indem Sie ihn an datetime.datetime übergeben. Datetime.datetime kann auch Werte bis zu Mikrosekunden verarbeiten, der Typ DATE kann jedoch nur Werte bis zu Sekunden verarbeiten, sodass Werte unter Sekunden abgeschnitten werden. Unten finden Sie Beispiele und Ausführungsergebnisse. Ich erhalte den Wert, der zum Zeitpunkt von SELECT um einen Tag vorverlegt wurde, damit ich sehen kann, dass er sich auf einen anderen Wert bezieht.
sample17a.py
import cx_Oracle
import datetime
USERID = "admin"
PASSWORD = "FooBar"
DESTINATION = "atp1_low"
SQL1 = "insert into sample17(col_date) values(:now)"
SQL2 = "select col_date + 1 from sample17"
sys_date = datetime.datetime.now()
print("AP-Wert:", sys_date)
with cx_Oracle.connect(USERID, PASSWORD, DESTINATION) as conn:
with conn.cursor() as cur:
cur.execute("truncate table sample17")
cur.execute(SQL1, [sys_date])
conn.commit()
val = cur.execute(SQL2).fetchone()[0]
print("DB-Wert:", val.strftime("%Y-%m-%d %H:%M:%S.%f"))
$ python sample17a.py
AP-Wert: 2020-09-26 10:48:02.605423
DB-Wert: 2020-09-27 10:48:02.000000
Wie der Typ DATE unterstützt auch der Typ TIMESTAMP den Python-Typ datetime.datetime. INSERT erfordert jedoch eine zusätzliche Codierung im Vergleich zum DATE-Typ. Wenn die Codierung mit dem Typ DATE identisch ist, wird sie genauso behandelt wie der Typ DATE, und Werte von weniger als einer Sekunde werden abgeschnitten. Im Moment,
Wird benötigt. Unten finden Sie Beispiele und Ausführungsergebnisse. Beachten Sie, dass die SQL-Anweisung, die eines Tages vorgerückt wird, im Gegensatz zum DATE-Typ INTERVAL verwendet. Wenn sie "+1" ist, wird sie in den DATE-Typ umgewandelt und Werte unter Sekunden werden abgeschnitten.
sample17b.py
import cx_Oracle
import datetime
USERID = "admin"
PASSWORD = "FooBar"
DESTINATION = "atp1_low"
SQL1 = "insert into sample17(col_ts) values(:now)"
SQL2 = "select col_ts + interval '1' day from sample17"
sys_date = datetime.datetime.now()
print("AP-Wert:", sys_date)
with cx_Oracle.connect(USERID, PASSWORD, DESTINATION) as conn:
with conn.cursor() as cur:
cur.execute("truncate table sample17")
cur.prepare(SQL1)
cur.setinputsizes(now=cx_Oracle.DB_TYPE_TIMESTAMP)
cur.execute(None, {"now":sys_date})
conn.commit()
val = cur.execute(SQL2).fetchone()[0]
print("DB-Wert:", val.strftime("%Y-%m-%d %H:%M:%S.%f"))
$ python sample17b.py
AP-Wert: 2020-09-26 23:51:27.832640
DB-Wert: 2020-09-27 23:51:27.832640
Diese Datentypen können mit derselben Codierung wie der TIMESTAMP-Typ behandelt werden. Setzen Sie die von Cursor.setinputsizes () angegebenen Typen auf cx_Oracle.DB_TYPE_TIMESTAMP_TZ bzw. cx_Oracle.DB_TYPE_TIMESTAMP_LTZ. Zum Zeitpunkt des Schreibens kann es jedoch aktualisiert werden, indem anstelle von nativ eine Erfassungszeit definiert wird. Im Fall von SELECT gehen die Zeitzoneninformationen jedoch verloren, da sie zur nativen Datumszeit empfangen werden. Soweit ich das Handbuch überprüfe, scheint es leider, dass selbst wenn ich Curosr.var () verwende, keine Einstellung zum Empfangen mit bekannter Datums- / Uhrzeitangabe vorhanden ist. Erwarten Sie daher bei Verwendung dieser Datentypen nicht, dass cx_Oracle die Zeitzonendifferenz absorbiert und unter Berücksichtigung der Zeitzonendifferenz mit Python oder SQL codiert (berechnen Sie die Zeitzonendifferenz selbst). Oder versuchen Sie, über eine Zeichenfolge zwischen Python und SQL zu wechseln (z. B. ISO 8601-Format). Das folgende Beispiel zeigt die Verwendung der Datumszeichenfolge im ISO 8601-Format.
sample17c.py
import cx_Oracle
import datetime
USERID = "admin"
PASSWORD = "FooBar"
DESTINATION = "atp1_low"
SQL1 = "insert into sample17(col_tz) values(to_utc_timestamp_tz(:now))"
SQL2 = f"select to_char(col_tz + interval '1' day, 'YYYY-MM-DD\"T\"HH24:MI:SS.ff6\"Z\"') from sample17"
sys_date = datetime.datetime.utcnow().replace(tzinfo=datetime.timezone.utc).isoformat()
print("AP-Wert:", sys_date)
with cx_Oracle.connect(USERID, PASSWORD, DESTINATION) as conn:
with conn.cursor() as cur:
cur.execute("truncate table sample17")
cur.execute(SQL1, [sys_date])
conn.commit()
val = cur.execute(SQL2).fetchone()[0]
print("DB-Wert:", val)
$ python sample17c.py
AP-Wert: 2020-09-27T07:05:42.948348+00:00
DB-Wert: 2020-09-28T07:05:42.948348Z
Recommended Posts