[PYTHON] [Introduction à cx_Oracle] (15e) Création d'un jeu de résultats dans un format autre que tapple

Table de sérialisation

Série: Introduction à cx_Oracle Contents

Environnement de vérification

--Utilisation d'Oracle Cloud

Aperçu

cx_Oracle renvoie le jeu de résultats sous forme de liste de tuples. Cependant, il peut arriver que vous souhaitiez le renvoyer sous forme de liste ou de dictionnaire. Cx_Oracle est préparé pour ce cas, je vais donc vous expliquer comment le faire.

Cursor.rowfactory L'attribut rowfactory de l'objet Cursor définit la méthode qui sera appelée lors de la récupération des enregistrements. Cet attribut produit des taples par défaut. En écrasant ce mouvement, il est possible de changer le format de l'enregistrement en une autre forme.

Jetons un coup d'œil au codage réel en révisant l'application suivante.

sample15a.py


import cx_Oracle

USERID = "admin"
PASSWORD = "FooBar"
DESTINATION = "atp1_low"
SQL = """
    select object_id, owner, object_name, object_type
      from all_objects
     order by object_id
     fetch first 5 rows only
"""

with cx_Oracle.connect(USERID, PASSWORD, DESTINATION) as connection:
    with connection.cursor() as cursor:
        for row in cursor.execute(SQL):
            print(row)
$ python sample15a.py
(2, 'SYS', 'C_OBJ#', 'CLUSTER')
(3, 'SYS', 'I_OBJ#', 'INDEX')
(4, 'SYS', 'TAB$', 'TABLE')
(5, 'SYS', 'CLU$', 'TABLE')
(6, 'SYS', 'C_TS#', 'CLUSTER')

Renvoie une liste d'ensembles de résultats

sample15b.py(Extrait)


with cx_Oracle.connect(USERID, PASSWORD, DESTINATION) as connection:
    with connection.cursor() as cursor:
        cursor.execute(SQL)
        cursor.rowfactory = lambda *args: list(args)
        rows = cursor.fetchall()
        for row in rows:
            print(row)

La quatrième ligne à partir du bas est l'implémentation de rowfactory. J'utilise une expression lambda pour convertir chaque enregistrement d'un taple en une liste. Seule cette ligne a été ajoutée et aucun autre codage n'a été modifié. Les résultats de l'exécution sont répertoriés ci-dessous.

$ python sample15b.py
[2, 'SYS', 'C_OBJ#', 'CLUSTER']
[3, 'SYS', 'I_OBJ#', 'INDEX']
[4, 'SYS', 'TAB$', 'TABLE']
[5, 'SYS', 'CLU$', 'TABLE']
[6, 'SYS', 'C_TS#', 'CLUSTER']

Renvoyer l'ensemble de résultats dans le dictionnaire

Il est également possible de renvoyer des enregistrements dans un dictionnaire qui utilise des noms de colonnes comme éléments.

sample15c.py(Extrait)


with cx_Oracle.connect(USERID, PASSWORD, DESTINATION) as connection:
    with connection.cursor() as cursor:
        cursor.execute(SQL)
        columns = [col[0] for col in cursor.description]
        cursor.rowfactory = lambda *args: dict(zip(columns, args))
        rows = cursor.fetchall()
        for row in rows:
            print(row)
        for row in rows:
            print(row["OBJECT_NAME"])

Le nom de la colonne est obtenu dans la 4ème ligne à partir du haut. curseur.description est un attribut en lecture seule sous la forme d'une liste de tuples qui stockent les métadonnées pour chaque colonne. L'élément numéro 0 de chaque taple de cet attribut est le nom de la colonne. La cinquième ligne à partir du haut utilise une expression lambda pour créer un dictionnaire en utilisant les informations de la ligne précédente. Le résultat de l'exécution est un dictionnaire comme indiqué ci-dessous.

$ python sample15c.py
{'OBJECT_ID': 2, 'OWNER': 'SYS', 'OBJECT_NAME': 'C_OBJ#', 'OBJECT_TYPE': 'CLUSTER'}
{'OBJECT_ID': 3, 'OWNER': 'SYS', 'OBJECT_NAME': 'I_OBJ#', 'OBJECT_TYPE': 'INDEX'}
{'OBJECT_ID': 4, 'OWNER': 'SYS', 'OBJECT_NAME': 'TAB$', 'OBJECT_TYPE': 'TABLE'}
{'OBJECT_ID': 5, 'OWNER': 'SYS', 'OBJECT_NAME': 'CLU$', 'OBJECT_TYPE': 'TABLE'}
{'OBJECT_ID': 6, 'OWNER': 'SYS', 'OBJECT_NAME': 'C_TS#', 'OBJECT_TYPE': 'CLUSTER'}
C_OBJ#
I_OBJ#
TAB$
CLU$
C_TS#

Renvoie le jeu de résultats sous forme de classe de données

rowfactory est également compatible avec Data Class, une nouvelle fonctionnalité de Python 3.7. Créer la même classe de données que le jeu de résultats semble être utile. Voir ci-dessous pour une description de la classe de données elle-même.

À partir de Python 3.7, les "classes de données" peuvent devenir la norme pour les définitions de classe

Vous trouverez ci-dessous des exemples et des résultats d'exécution.

sample15d.py


import cx_Oracle
from dataclasses import dataclass

@dataclass
class AllObject:
    object_id: int
    owner: str
    object_name: str
    object_type: str


    def display(self):
        return f"{self.owner}.{self.object_name}Est{self.object_type}(ID:{self.object_id})est"


USERID = "admin"
PASSWORD = "FooBar"
DESTINATION = "atp1_low"
SQL = """
    select object_id, owner, object_name, object_type
      from all_objects
     order by object_id
     fetch first 5 rows only
"""

with cx_Oracle.connect(USERID, PASSWORD, DESTINATION) as connection:
    with connection.cursor() as cursor:
        cursor.execute(SQL)
        cursor.rowfactory = lambda *args: AllObject(*args)
        rows = cursor.fetchall()
        [print(r.display()) for r in rows]
$ python sample15d.py
SYS.C_OBJ#Est CLUSTER(ID:2)est
SYS.I_OBJ#Est INDEX(ID:3)est
SYS.TAB$Est TABLE(ID:4)est
SYS.CLU$Est TABLE(ID:5)est
SYS.C_TS#Est CLUSTER(ID:6)est

Recommended Posts

[Introduction à cx_Oracle] (15e) Création d'un jeu de résultats dans un format autre que tapple
[Introduction à cx_Oracle] (8e) version de cx_Oracle 8.0
[Introduction à cx_Oracle] (Partie 4) Récupération et défilement du jeu de résultats
[Introduction à cx_Oracle] (12e) Gestion des exceptions DB
[Introduction à cx_Oracle] (17e) Gestion du type de date
[Introduction à cx_Oracle] (16ème) Gestion des types LOB
Comment effacer un taple dans une liste (Python)
[Introduction à cx_Oracle] (5e) Gestion des données japonaises
Introduction à l'algèbre linéaire avec Python: Décomposition A = LU
Définir une tâche pour définir l'environnement de fabric dans YAML
Essayez de créer le format de fichier DeepZoom .DZI en Python
Comment sortir un document au format pdf avec Sphinx
[Introduction à cx_Oracle] (10e) Instruction Update DML et DDL / DCL
Comment extraire un index autre qu'un index spécifique avec Numpy
Comment utiliser un fichier autre que .fabricrc comme fichier de configuration