[Einführung in cx_Oracle] (Teil 9) Zuordnung von DB- und Python-Datentypen (Version 8 oder höher)

Überprüfungsumgebung

Einführung

Natürlich unterscheiden sich die Datentypen zwischen Oracle Database und Python. In diesem Artikel werde ich erklären, wie cx_Oracle zwischen den beiden Datentypen vermittelt.

Übersicht über die Datentypzuordnung

Welcher Datentyp der Oracle-Datenbank letztendlich welchem Python-Datentyp zugeordnet ist, finden Sie im Handbuch cx_Oracle (https://cx-oracle.readthedocs.io/en/latest/user_guide/sql_execution.html). Es ist in # fetch-data-types zusammengefasst. Datentypaustausch zwischen Oracle Database und Python Oracle Database-Datentyp ⇔ cx_Oracle-Datentyp ⇔ Python-Datentyp Es wird durch den Fluss umgewandelt. Grundsätzlich gibt es einen cx_Oracle-Datentyp mit einem Namen, der mit "DB_TYPE_" beginnt und einem bestimmten Oracle Database-Datentyp entspricht. Der Datentyp cx_Oracle, der bis cx_Oracle 7.3 (vor 8) verwendet wurde, kann weiterhin als Synonim verwendet werden. Da er jedoch in Zukunft veraltet sein wird, wenn eine neue Anwendung mit Version 8 erstellt oder der Datentyp cx_Oracle verwendet wird Wenn Änderungen vorgenommen werden müssen, stellen Sie sicher, dass Sie den Datentyp cx_Oracle verwenden, der mit "DB_TYPE_" beginnt. Darüber hinaus werden in der DB-API definierte Datentypen weiterhin unterstützt.

■ Datentypzuordnung

Oracle Database-Datentyp cx_Oracle-Datentyp Python-Datentyp
CHA cx_Oracle.DB_TYPE_CHAR str
VARCHAR2 cx_Oracle.DB_TYPE_VARCHAR str
NUMBER cx_Oracle.DB_TYPE_NUMBER float oder int
DATE cx_Oracle.DB_TYPE_DATE datetime.datetime
TIMESTAMP cx_Oracle.DB_TYPE_TIMESTAMP datetime.datetime
RAW cx_Oracle.DB_TYPE_RAW bytes

■ Datentypzuordnung, die der [DB-API] entspricht (https://www.python.org/dev/peps/pep-0249/)

Oracle Database-Datentyp cx_Oracle-Datentyp Python-Datentyp
CHAR, VARCHAR2 cx_Oracle.STRING str
NUMBER cx_Oracle.NUMBER float oder int
DATE cx_Oracle.DATETIME datetime.datetime
TIMESTAMP cx_Oracle.TIMESTAMP datetime.datetime
RAW cx_Oracle.BINARY bytes

■ Manuelle Referenz DB API-kompatibler cx_Oracle-Datentyp cx_Oracle's eigener Datentyp

Hierbei ist zu beachten, dass es zwei Arten von Python-Datentypen gibt, die den Typ NUMBER unterstützen: float und int. Dies hängt von der Definition des NUMBER-Typs und dem gespeicherten Wert ab. Überprüfen Sie das Ausführungsergebnis der folgenden Beispielanwendung.

sample06a.py(Erneut veröffentlichen)


import cx_Oracle

USERID = "admin"
PASSWORD = "FooBar"
DESTINATION = "atp1_low"
SQL1 = """
        create table sample06a (col1 number, col2 number, col3 number,
          col4 number(5, 0), col5 number(5, 0), col6 number(5, 2),
          col7 number(5, 2), col8 number(5, 2))
"""
SQL2 = "insert into sample06a values(7, 7.0, 7.1, 7, 7.0, 7, 7.0, 7.1)"
SQL3 = "commit"
SQL4 = "select * from sample06a"

with cx_Oracle.connect(USERID, PASSWORD, DESTINATION) as connection:
        with connection.cursor() as cursor:
                cursor.execute(SQL1)
                cursor.execute(SQL2)
                cursor.execute(SQL3)
                row = cursor.execute(SQL4).fetchone()
                print(f""7" für NUMMER: {type(row[0])}")
                print(f""7" in NUMMER.0」 : {type(row[1])}")
                print(f""7" in NUMMER.1」 : {type(row[2])}")
                print(f"NUMBER(5, 0)Auf "7": {type(row[3])}")
                print(f"NUMBER(5, 0)Zu "7.0」 : {type(row[4])}")
                print(f"NUMBER(5, 2)Auf "7": {type(row[5])}")
                print(f"NUMBER(5, 2)Zu "7.0」 : {type(row[6])}")
                print(f"NUMBER(5, 2)Zu "7.1」 : {type(row[7])}")

Ausführungsergebnis


$ python sample06a.py
"7" für NUMMER: <class 'int'>
"7" in NUMMER.0」 : <class 'int'>
"7" in NUMMER.1」 : <class 'float'>
NUMBER(5, 0)Auf "7": <class 'int'>
NUMBER(5, 0)Zu "7.0」 : <class 'int'>
NUMBER(5, 2)Auf "7": <class 'float'>
NUMBER(5, 2)Zu "7.0」 : <class 'float'>
NUMBER(5, 2)Zu "7.1」 : <class 'float'>

Aus dem Ausführungsergebnis sind die folgenden Regeln ersichtlich.

Es gibt kein besonderes Problem mit dem Typ int, aber das Problem ist der Typ float. Bei Geschäftsanwendungen, bei denen häufig Oracle Database verwendet wird, besteht die Sorge, dass Rundungsfehler auftreten und Probleme verursachen können, insbesondere bei Informationen zu Geld und schwebenden Brüchen. In solchen Fällen verwendet Python das Dezimalmodul, um damit umzugehen, aber cx_Oracle selbst konvertiert nicht in Dezimalzahlen, wie in der obigen Tabelle gezeigt. Cx_Oracle sieht jedoch solche Fälle vor.

outputtypehandler Wenn Sie aus den oben genannten Gründen die Konvertierungsspezifikation des Standarddatentyps von cx_Oracle nicht verwenden möchten und Ihre eigene Datenkonvertierungsfunktion im Attribut outputtypehandler des Connection-Objekts angeben, wird diese Funktion anstelle der ursprünglichen Konvertierungsregel konvertiert. Wird verwendet. Im Fall von Python → Oracle ist dies das Attribut inputtypehandler.

sample09a.py


import cx_Oracle
import decimal

USERID = "admin"
PASSWORD = "FooBar"
DESTINATION = "atp1_low"
SQL = "select * from sample06a"

def num2Dec(cursor, name, defaultType, size, precision, scale):
        if defaultType == cx_Oracle.DB_TYPE_NUMBER:
                return cursor.var(decimal.Decimal, arraysize=cursor.arraysize)

with cx_Oracle.connect(USERID, PASSWORD, DESTINATION) as connection:
        with connection.cursor() as cursor:
                row = cursor.execute(SQL).fetchone()
                print(f"Kein OutputTypeHandler")
                print(f"Stellen Sie NUMBER auf "7" und verdreifachen Sie: {row[0] * 3}")
                print(f""7" in NUMMER.1 ”wird gesetzt und verdreifacht: {row[2] * 3}")
        with connection.cursor() as cursor:
                cursor.outputtypehandler = num2Dec
                row = cursor.execute(SQL).fetchone()
                print(f"Mit OutputTypeHandler")
                print(f"Stellen Sie NUMBER auf "7" und verdreifachen Sie: {row[0] * 3}")
                print(f""7" in NUMMER.1 ”wird gesetzt und verdreifacht: {row[2] * 3}")

Bitte beachten Sie, dass dieses Skript die Tabelle und die Daten auswählt, die im vorherigen Skript erstellt wurden. Die num2Dec-Funktion in der Mitte des Skripts ist die eigentliche neue Datenkonvertierungsroutine. Wenn Sie die Funktion num2Dec als Ausgabetyphandler in der 5. Zeile von unten festlegen, funktioniert diese Funktion. Sie können einen beliebigen Funktionsnamen und Argumentnamen des Ausgabetyphandlers angeben. Die Angabe des Arguments ist jedoch wie folgt definiert, und alle 6 sind als Argumente erforderlich, auch wenn sie nicht in der Funktion verwendet werden.

Argumentreihenfolge Bedeutung
1 Zu bedienendes Cursorobjekt
2 Spaltenname
3 Spalte cx_Oracle-Datentyp
4 Spaltengröße
5 Anzahl der Bruchstellen in der Spalte(NUMBER(p,s)S.)
6 Gesamtzahl der Stellen in der Spalte(NUMBER(p,s)P.)

Die var-Methode des Cursor-Objekts im Beispiel ist eine Methode, die die Variableninformationen für die Variable in der entsprechenden Spalte auf die durch das Argument angegebene Form aktualisiert. Geben Sie im ersten Argument den zu ändernden Datentyp an. Muss angegeben werden. Die var-Methode selbst ist eine Methode, die häufig für andere Zwecke als den Ausgabetyphandler verwendet wird. Das zweite und die nachfolgenden Argumente sind als Methodenspezifikation optional. Für die Verwendung des Ausgabetyphandlers ist jedoch ein Parameter namens arraysize erforderlich, und die Arraysize des Cursorobjekts wird festgelegt. Muss eingestellt werden.

Ausführungsergebnis


$ python sample09a.py
Kein Handler für Ausgabetypen
Stellen Sie NUMBER auf "7" und verdreifachen Sie: 21
"7" in NUMMER.1 ”wird gesetzt und verdreifacht: 21.299999999999997
Mit Ausgabetyp-Handler
Stellen Sie NUMBER auf "7" und verdreifachen Sie: 21
"7" in NUMMER.1 ”wird gesetzt und verdreifacht: 21.3

Wenn Sie den Ausgabetyphandler wie das Ausführungsergebnis durchlaufen, wird das Berechnungsergebnis eher erwartet. Anstatt den Ausgabetyphandler zu verwenden, können Sie ihn natürlich in einer Python-Float-Typvariablen empfangen und dann in eine Dezimalzahl konvertieren. Wenn Sie jedoch eine große Anzahl unterstützter Spalten haben, können Sie den Ausgabetyphandler problemlos codieren.

Recommended Posts

[Einführung in cx_Oracle] (Teil 9) Zuordnung von DB- und Python-Datentypen (Version 8 oder höher)
[Einführung in cx_Oracle] (Teil 6) Zuordnung von DB- und Python-Datentypen
Lösen der Einführung von AOJ in Algorithmen und Datenstrukturen in Python -Part2-
Lösen der Einführung von AOJ in Algorithmen und Datenstrukturen in Python -Part4-
Lösen der Einführung von AOJ in Algorithmen und Datenstrukturen in Python -Part3-
Einführung in Python (Python-Version APG4b)
[Einführung in cx_Oracle] (Teil 4) Abrufen und Scrollen der Ergebnismenge
[Einführung in Data Scientists] Grundlagen von Python ♬ Funktionen und Klassen
[Einführung in Python] Kombinieren Sie Nikkei-Durchschnitts- und NY Dow-CSV-Daten
Trainieren! !! Einführung in Python Type (Type Hints)
[Einführung in Python3 Tag 1] Programmierung und Python
Einführung in Python Hands On Teil 1
[AWS SAM] Einführung in die Python-Version
[Einführung in cx_Oracle] (Teil 2) Grundlagen zum Verbinden und Trennen mit Oracle Database
[Einführung in Data Scientists] Grundlagen von Python ♬ Bedingte Verzweigung und Schleifen
[Einführung in Python] Verwendung des Booleschen Operators (und ・ oder ・ nicht)
[Einführung in Data Scientists] Grundlagen von Python ♬ Funktionen und anonyme Funktionen usw.
[Einführung in die Udemy Python3 + -Anwendung] 28. Kollektiver Typ
[Einführung in Python3, Tag 17] Kapitel 8 Datenziele (8.1-8.2.5)
[Einführung in Python3, Tag 17] Kapitel 8 Datenziele (8.3-8.3.6.1)
Web-WF Python Tornado Teil 3 (Einführung in Openpyexcel)
[Einführung in die Udemy Python3 + -Anwendung] 21. Taple-Typ
[Einführung in Python3 Tag 19] Kapitel 8 Datenziele (8.4-8.5)
[Einführung in cx_Oracle] (12.) DB-Ausnahmebehandlung
[Einführung in cx_Oracle] (17.) Datumsbehandlung
[Einführung in Python3 Tag 18] Kapitel 8 Datenziele (8.3.6.2 bis 8.3.6.3)
[Einführung in die Udemy Python3 + -Anwendung] 24. Wörterbuchtyp
Komprimieren Sie Python-Daten und schreiben Sie in SQLite
[Einführung in die Udemy Python3 + -Anwendung] 16. Listentyp
[Einführung in Data Scientist] Grundlagen von Python ♬
[Einführung in Python3 Tag 12] Kapitel 6 Objekte und Klassen (6.3-6.15)
[Cx_Oracle Primer] (Teil 3) Grundlagen zum Durchsuchen von Tabellen
[Python] Lesen von Daten aus CIFAR-10 und CIFAR-100
[Einführung in Python3, Tag 22] Kapitel 11 Parallele Verarbeitung und Vernetzung (11.1 bis 11.3)
[Einführung in Python] Umgang mit Daten im JSON-Format
[Einführung in die Udemy Python3 + -Anwendung] 64. Namespace und Gültigkeitsbereich
[Einführung in Python3 Tag 11] Kapitel 6 Objekte und Klassen (6.1-6.2)
[Einführung in cx_Oracle] (5.) Umgang mit japanischen Daten
[Einführung in cx_Oracle] (Teil 7) Umgang mit Bindevariablen
[Python3] Herstellen einer Verbindung zur Oracle-Datenbank und Ausführen von SQL [cx_Oracle]
Probieren Sie die DB-Operation mit Python aus und visualisieren Sie sie mit d3
Lesehinweis: Einführung in die Datenanalyse mit Python
[Einführung in cx_Oracle] (Teil 11) Grundlagen der PL / SQL-Ausführung
[Einführung in die Udemy Python3 + -Anwendung] 68. Importanweisung und AS
Python # So überprüfen Sie Typ und Typ für Super-Anfänger
[Einführung in cx_Oracle] (13.) Verbindung über Verbindungspool (Client-Seite)
Einführung in Python numpy pandas matplotlib (für ~ B3 ~ part2)
[Technisches Buch] Einführung in die Datenanalyse mit Python -1 Kapitel Einführung-
Lesen von Notizen (in Python und Stan) zur Einführung in die statistische Modellierung für die Datenanalyse (Midorimoto)
Einführung in die Python-Sprache
Einführung in OpenCV (Python) - (2)
Einführung in PyQt4 Teil 1
Ich möchte Daten mit Python analysieren können (Teil 3)
Aktualisieren Sie Raspberry Pi Python mit pyenv auf 3.7 oder höher
[Einführung in Data Scientists] Deskriptive Statistik und einfache Regressionsanalyse ♬
Ich möchte Daten mit Python analysieren können (Teil 1)
[Einführung in die Udemy Python3 + -Anwendung] 42. für Anweisung, break-Anweisung und continue-Anweisung
[Einführung in die Udemy Python3 + -Anwendung] 39. while-Anweisung, continue-Anweisung und break-Anweisung
[Einführung in cx_Oracle] (10.) Aktualisieren Sie die DML-Anweisung und die DDL / DCL-Anweisung
[Einführung in die Udemy Python3 + -Anwendung] 36. Verwendung von In und Not