Série: Introduction à cx_Oracle Contents
--Utilisation d'Oracle Cloud
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')
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']
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#
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.
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