Download Documentazione FAQ Aiutaci!!!


Specifiche dell'API Python per i Database v.2.0

Questa API è stata creata allo scopo di favorire una certa uniformità dei moduli Python usati per accedere ai vari database. Speriamo di ottenere così del codice più semplice da capire e facilmente portabile su database diversi, e di ampliare in qualità e quantità il supporto Python ai database.

Le specifiche consistono di diverse sezioni:

Commenti e domande su tali specifiche possono essere inviate al SIG per le Interfacce Python ai Database.

Per maggiori informazioni sull'interfacciamento ai database con Python si veda la Database Topics Guide su http://www.python.org/[off-site link].

idea! Su questo sito è anche disponibile la documentazione in italiano di mysqldb, un modulo per MySQL conforme all'API DB 2.0.

L'originale in inglese del documento è disponibile presso www.python.org[off-site link].

Questo documento descrive le Specifiche dell'API Python per i Database v.2.0. La precedente versione 1.0[off-site link] è ancora disponibile come riferimento. Gli scrittori di package sono fortemente incoraggiati a usare la versione 2.0 qui presentata come base per le loro nuove interfacce.


Interfaccia del Modulo

    L'accesso al database è reso disponibile per mezzo di oggetti Connessione. Il modulo deve fornire il seguente costruttore per essi:

    connect(parametri...)
    Il costruttore per la creazione di una connessione al database. Restituisce un oggetto Connessione. Accetta un certo numero di parametri in dipendenza dal singolo database. [1]

    Devono essere definiti i seguenti nomi globali di modulo:

    apilevel
    Costante stringa che specifica il livello della API DB supportata. Attualmente sono permesse solo le stringhe '1.0' e '2.0'.

    Ove assente si deve assumere che l'interfaccia non sia conforme alla API 2.0 e si basi sulla Database API 1.0[off-site link].

    threadsafety
    Costante intera che specifica il livello di supporto al multithreading offerto. I valori possibili sono:
    0 = i thread non possono condividere il modulo.
    1 = i thread possono condividere il modulo ma non le connessioni.
    2 = i thread possono condividere il modulo e le connessioni.
    3 = i thread possono condividere il modulo, le connessioni e i cursori.

    "Condivisione" nel contesto soprastante significa che due thread possono usare una risorsa senza aver bisogno di implementare un meccanismo di lock tramite mutex. Si noti che non sempre si può rendere "a prova di [uso coi] thread" [`thread safe'] una risorsa esterna con un controllo degli accessi tramite mutex: la risorsa potrebbe fare assegnamento su variabili globali o altre risorse esterne che sono al di fuori del nostro controllo.

    paramstyle
    Costante stringa che specifica il tipo di formattazione del marcatore di parametro atteso dall'interfaccia. I valori possibili sono [2]:
    'qmark' = con punto interrogativo, p.e. '...WHERE name=?'
    'numeric' = in stile numerico, posizionale, p.e. '...WHERE name=:1'
    'named' = per nome, p.e. '...WHERE name=:name'
    'format' = nel codice di formato della printf ANSI C, p.e. '...WHERE name=%s'
    'pyformat' = nei codici di formato estesi Python, p.e. '...WHERE name=%(name)s'

    Il modulo dovrebbe rendere disponibile ogni informazione di errore attraverso le eccezioni seguenti, o loro sottoclassi:

    Warning
    Eccezione sollevata per avvisi importanti, quali troncamento di dati nel corso del loro inserimento, ecc. Dev'essere una sottoclasse dell'eccezione Python StandardError (definita nel modulo exceptions).

    Error
    Eccezione che costituisce la classe base di tutte le altre eccezioni di errore. La si può utilizzare per catturare tutti gli errori con un singolo except. Gli avvisi [`warning'] non sono considerati errori, perciò non dovrebbero usare questa classe come base. Dev'essere una sottoclasse dell'eccezione Python StandardError (definita nel modulo exceptions).

    InterfaceError
    Eccezione sollevata per errori legati all'interfaccia più che al database stesso. Dev'essere una sottoclasse di Error.

    DatabaseError
    Eccezione sollevata per errori sul database. Dev'essere una sottoclasse di Error.

    DataError
    Eccezione sollevata per errori dovuti a problemi con dati calcolati, come divisioni per zero, valori numerici fuori dall'intervallo consentito, ecc. Dev'essere una sottoclasse di DatabaseError.

    OperationalError
    Eccezione sollevata per errori legati a operazioni del database non necessariamente sotto il controllo del programmatore, per esempio quando avviene una disconnessione inaspettata, non viene trovato il nome della sorgente dei dati, non è possibile effettuare una transazione, si ha un errore di memoria durante l'elaborazione, ecc. Dev'essere una sottoclasse di DatabaseError.

    IntegrityError
    Eccezione sollevata quando è interessata l'integrità relazionale del database, p.e. fallisce l'ispezione di una chiave esterna. Dev'essere una sottoclasse di DatabaseError.

    InternalError
    Eccezione sollevata per un errore interno del database, p.e. il cursore non è più valido, la transazione non è sincronizzata ecc. Dev'essere una sottoclasse di DatabaseError.

    ProgrammingError
    Eccezione sollevata in caso si tratti di errori diretti di programmazione, p.e. una tabella non viene trovata o è già esistente, c'è un errore di sintassi nel comando SQL, è stato specificato un numero errato di parametri, ecc. Dev'essere una sottoclasse di DatabaseError.

    NotSupportedError
    Eccezione sollevata quando viene usato un metodo o un'API non supportato dal database, p.e. viene richiesto un .rollback() su una connessione che non supporta le transazioni o le ha disabilitate. Dev'essere una sottoclasse di DatabaseError.

    Questo è lo schema di ereditarietà delle eccezioni:

    StandardError
    |__Warning
    |__Error
       |__InterfaceError
       |__DatabaseError
          |__DataError
          |__OperationalError
          |__IntegrityError
          |__InternalError
          |__ProgrammingError
          |__NotSupportedError
      

    Nota: I valori di tali eccezioni non sono definiti. Dovrebbero comunque fornire all'utente un'idea abbastanza chiara sull'origine del problema.

Oggetti Connessione

    Gli oggetti Connessione dovrebbero rispondere ai metodi seguenti:

    close()
    Chiude la connessione al momento (piuttosto che alla chiamata di __del__). La connessione sarà inutilizzabile da qui in avanti: in caso venga tentata una qualsiasi operazione sulla connessione verrà sollevata un'eccezione Error (o una sua sottoclasse). Lo stesso accade a tutti gli oggetti Cursore che tentino di usare la connessione.

    commit()
    Effettua il commit di qualsiasi transazione in sospeso. Si noti che se il database supporta nativamente una funzionalità di auto-commit essa dev'essere disabilitata all'inizio. L'interfaccia può comprendere un metodo per rimetterla in funzione.

    I moduli per database che non supportano le transazioni dovrebbero comunque implementarlo, come metodo vuoto, con funzionalità nulla.

    rollback()
    Questo metodo è opzionale, dato che non tutti i database offrono supporto alle transazioni.[3]

    In caso un database supporti le transazioni, questo metodo fa sì che esso ritorni allo stato precedente a ogni transazione in sospeso. Chiudere una connessione senza prima effettuare il commit delle modifiche provocherà l'esecuzione di un rollback implicito.

    cursor()
    Restituisce un nuovo oggetto Cursore utilizzando la connessione. Se il database non fornisce supporto diretto al concetto di cursore, il modulo dovrà emulare i cursori con altri mezzi, entro i limiti di quanto è necessario secondo le specifiche:[4]

Oggetti Cursore

    Questi oggetti rappresentano un cursore del database, usato nella gestione del contesto di un'operazione di fetch [prelievo di dati NdT].

    Gli oggetti Cursore dovrebbero rispondere ai seguenti metodi e attributi:

    description
    È un attributo a sola lettura che consiste di una sequenza di sequenze a sette elementi. Ognuna di queste sequenze contiene informazioni che descrivono una colonna di risultati: (name, type_code, display_size, internal_size, precision, scale, null_ok). L'attributo sarà None per operazioni che non restituiscono righe, o nel caso non sia stata ancora effettuata un'operazione tramite il metodo executeXXX.

    type_code può essere interpretato comparandolo agli oggetti Tipo specificati più sotto.

    rowcount
    È un attributo a sola lettura che specifica il numero di righe che l'ultimo executeXXX() ha prodotto (per comandi DQL come select) o comunque interessato (per comandi DML come update o insert).

    Il valore dell'attributo è pari a -1 nel caso non sia stato eseguito alcun executeXXX() sul cursore o il conteggio delle righe dell'ultima operazione non sia calcolabile dall'interfaccia.[7]

    callproc(nomeprocedura[,parametri])
    Questo metodo è opzionale, dato che non tutti i database supportano le "stored procedure".[3]

    Invoca la stored procedure del database passata con nomeprocedura. La sequenza dei parametri deve contenere una voce per ogni argomento richiesto dalla procedura. Il risultato della chiamata è restituito come copia modificata della sequenza in ingresso. I parametri in ingresso non vengono toccati, i parametri in uscita e ingresso/uscita vengono eventualmente rimpiazzati con nuovi valori.

    La procedura può anche fornire come risultato un insieme di righe, che dev'essere quindi reso disponibile attraverso i metodi standard fetchXXX().

    close()
    Chiude il cursore al momento (piuttosto che alla chiamata di __del__). Il cursore non sarà più utilizzabile da qui in avanti: in caso venga tentata una qualsiasi operazione sul cursore verrà sollevata un'eccezione Error (o una sua sottoclasse).

    execute(operazione[,parametri])
    Prepara ed esegue un'operazione sul database (interrogazione o comando). I parametri possono essere passati come sequenza o dizionario e verranno associati a variabili nell'operazione. Le variabili sono specificate in una notazione specifica al database (si veda l'attributo di modulo paramstyle per i dettagli). [5]

    Il cursore conserverà un riferimento all'operazione. Se lo stesso oggetto operazione gli verrà passato nuovamente, il cursore saraà così in grado di ottimizzare il suo comportamento. Questo è molto efficace in caso di algoritmi in cui la stessa operazione viene svolta molte volte con parametri diversi.

    Per garantire la massima efficienza nel riuso di un'operazione è bene usare il metodo setinputsizes() per specificare anzitempo i tipi e le dimensioni dei parametri. Un parametro può anche non corrispondere all'informazione definita in tal modo; l'implementazione dovrebbe compensare automaticamente, a prezzo di un'eventuale perdita in efficienza.

    I parametri possono anche essere specificati come lista di tuple, p.e. per inserire più righe in una singola operazione, ma quest'uso è sconsigliato, si dovrebbe piuttosto usare executemany().

    I valori restituiti non sono definiti.

    executemany(operazione,sequenza_di_parametri)
    Prepara un'operazione sul database (interrogazione o comando), quindi la esegue usando tutte le sequenze o dizionari di parametri trovati in sequenza_di_parametri.

    I moduli sono liberi di implementare questo metodo usando invocazioni multiple del metodo execute() o usando operazioni con array per far sì che il database processi la sequenza come un tutt'uno in una singola chiamata.

    A questo metodo si applicano le stesse considerazioni espresse per execute().

    I valori restituiti non sono definiti.

    fetchone()
    Preleva [`fetch'] la riga seguente dal risultato di un'interrogazione, restituendo una singola sequenza oppure None quando non ci sono più dati disponibili. [6]

    In caso l'ultima invocazione di executeXXX() non abbia prodotto alcun risultato o non sia ancora stata inoltrata alcuna invocazione, verrà sollevata un'eccezione Error (o una sua sottoclasse).

    fetchmany([size=cursor.arraysize])
    Preleva l'insieme successivo di righe facenti parti del risultato di un'interrogazione, restituendo una sequenza di sequenze (p.e. una lista di tuple). In caso non siano più disponibili altre righe, viene restituita una sequenza vuota.

    Il numero di righe da prelevare a ogni chiamata è specificato dal parametro. Se non viene passato esplicitamente, sarà l'attributo arraysize del cursore a determinare il numero di righe che verranno prelevate. Il metodo dovrebbe tentare di prelevare tante righe quante indicate dal parametro size. Ove questo non fosse possibile perché non ci sono abbastanza righe disponibili, ne verranno restituite in numero minore.

    In caso l'ultima invocazione di executeXXX() non abbia prodotto alcun risultato o non sia ancora stata inoltrata alcuna invocazione, verrà sollevata un'eccezione Error (o una sua sottoclasse).

    Si noti che ci sono alcune considerazioni da fare circa l'influenza del parametro size sulle prestazioni. Per ottenere prestazioni ottimali di solito la cosa migliore è usare l'attributo arraysize. Se viene passato esplicitamente un parametro size, risulta ottimale mantenere lo stesso valore nelle invocazioni successive di fetchmany().

    fetchall()
    Preleva tutte le righe (restanti) dal risultato di una interrogazione, restituendole come sequenza di sequenze (p.e. una lista di tuple). Si noti che l'attributo arraysize del cursore può influenzare la velocità dell'operazione.

    In caso l'ultima invocazione di executeXXX() non abbia prodotto alcun risultato o non sia ancora stata inoltrata alcuna invocazione, verrà sollevata un'eccezione Error (o una sua sottoclasse).

    nextset()
    Questo metodo è opzionale, dato che non tutti i database supportano risultati multipli. [3]

    Questo metodo farà saltare il cursore al prossimo risultato disponibile, scartando tutte le righe rimanenti del risultato corrente.

    Se non ci sono più altri risultati, il metodo restituisce None. In caso contrario restituisce un valore vero, e le chiamate ai metodi fetch che seguono restituiranno righe appartenenti al nuovo risultato.

    In caso l'ultima invocazione di executeXXX() non abbia prodotto alcun risultato o non sia ancora stata inoltrata alcuna invocazione verrà sollevata un'eccezione Error (o una sua sottoclasse).

    arraysize
    Questo attributo scrivibile specifica il numero di righe da prelevare in una singola invocazione di fetchmany(). Il valore predefinito è 1, il che significa che verrà prelevata una sola riga alla volta.

    Le diverse implementazioni devono rispettare questo valore per quanto concerne il metodo fetchmany(), ma sono libere di interagire con il database una singola riga alla volta. Tale valore può essere usato anche nell'implementazione di executemany().

    setinputsizes(sizes)
    Questo attributo può essere usato prima di un executeXXX() per definire in anticipo aree di memoria per i parametri dell'operazione.

    sizes è specificato come sequenza, in cui a ogni elemento corrisponde un parametro in ingresso. L'elemento dovrebbe essere un oggetto Tipo che corrisponda a quanto verrà usato in ingresso, oppure un intero che specifichi la lunghezza massima di una stringa parametro. Se l'elemento è None, allora non verrà riservata un'area di memoria predefinita per la colonna corrispondente (utile per nel caso di input molto grossi).

    Questo metodo dovrebbe essere usato prima dell'invocazione di executeXXX().

    Le varie implementazioni sono libere di non fargli fare in realtà nulla e gli utenti possono tranquillamente fare a meno di usarlo.

    setoutputsize(size[,column])
    Imposta la dimensione del buffer di una colonna, utile nel caso di prelievi di dati voluminosi (p.e. LONG, BLOB, ecc.). La colonna è specificata secondo l'indice nella sequenza risultato. Se non viene specificata, allora tali dimensioni di default verranno applicate a tutte le colonne molto ampie del cursore.

    Questo metodo dovrebbe essere usato prima dell'invocazione di executeXXX().

    Le varie implementazioni sono libere di non fargli fare in realtà nulla e gli utenti possono tranquillamente fare a meno di usarlo.

Oggetti Tipo e Costruttori

    Molti database hanno bisogno di avere l'input in un particolare formato per associarlo ai parametri di ingresso di un'operazione. Per esempio, se un input è destinato a finire in una colonna DATE [data anno-mese-giorno] allora dev'essere connessi al database come stringa di un formato particolare. Problemi simili esistono per colonne Identificativo o dati binari molto voluminosi (p.e. BLOB). Tutto ciò è fonte di potenziali problemi per Python, dato che i parametri per il metodo executeXXX() non sono tipizzati. Quando il modulo database vede un oggetto stringa Python, non sa se debba essere connesso come una semplice colonna CHAR, come un elemento BINARY o come una DATE.

    Per risolvere questo problema, un modulo deve fornire i costruttori definiti più avanti per creare oggetti che possono conservare valori speciali. Quando verranno passati ai metodi del cursore il modulo potrà discernere il tipo appropriato del parametro d'ingresso e connetterlo opportunamente.

    L'attributo description di un oggetto Cursore restituisce informazioni su ciascuna delle colonne del risultato di un'interrogazione. type_code dev'essere uguale a uno degli oggetti Tipo definiti più. Gli oggetti Tipo possono essere uguali a più di un codice tipo (p.e. DATETIME potrebbe essere uguale ai codici tipo per le colonne DATE, TIME e TIMESTAMP [informazione oraria pi&ugfrave; completa del tipo TIME, prevede tutte le informazioni dell'anno a, eventualmente, frazioni di secondo NdT]; si veda Suggerimenti per l'implementazione per i dettagli).

    Il modulo esporta i seguenti costruttori e insiemi a singolo elemento [`singleton']:

    Date(anno,mese,giorno)
    Questa funzione crea un oggetto che contiene un valore DATE.

    Time(ore,minuti,secondi)
    Questa funzione crea un oggetto che contiene un valore TIME.

    Timestamp(anno,mese,giorno,ore,minuti,secondi)
    Questa funzione crea un oggetto che contiene un valore TIMESTAMP.

    DateFromTicks(istante)
    Questa funzione crea un oggetto che contiene un valore DATE che parte da un dato valore di tick (in secondi dall'ora zero del sistema, si veda la documentazione del modulo Python standard time per dettagli).

    TimeFromTicks(ticks)
    Questa funzione crea un oggetto che contiene un valore TIME che parte dal numero di tick dato (in secondi dall'ora zero del sistema, si veda la documentazione del modulo Python standard time per dettagli).

    TimestampFromTicks(ticks)
    Questa funzione crea un oggetto che contiene un valore TIMESTAMP che parte da un dato valore di tick (in secondi dall'ora zero del sistema, si veda la documentazione del modulo Python standard time per dettagli).

    Binary(string)
    Questa funzione crea un oggetto capace di contenere un valore stringa binario (lungo).

    STRING
    Questo oggetto tipo è usato per descrivere colonne basate su stringhe (p.e. CHAR).

    BINARY
    Questo oggetto tipo è usato per descrivere colonne di dati binari (lunghi) (p.e. LONG, RAW, BLOB).

    NUMBER
    Questo oggetto tipo è usato per descrivere colonne numeriche.

    DATETIME
    Questo oggetto tipo è usato per descrivere colonne DATE/TIME.

    ROWID
    Questo oggetto tipo è usato per descrivere colonne Identificativo.

    I valori NULL di SQL sono rappresentati in Python da None sia in ingresso che in uscita.

    Nota: l'uso dei tick Unix per interfacciarsi a database può causare problemi a causa dell'intervallo limitato di date che sono in grado di coprire.

Suggerimenti per l'implementazione

  • I tipi di oggetto consigliati per date e orari sono quelli definiti nel package mxDateTime [off-site link]. Esso fornisce tutti i costruttori e i metodi necessari sia a livello Python che C.

  • Il tipo consigliato per gli oggetti Binary sono i buffer, disponibili come standard in Python a partire dalla versione 1.5.2. Si faccia riferimento alla documentazione Python per i dettagli. Per informazioni sull'interfaccia C si veda Include/bufferobject.h e Objects/bufferobject.c nella distribuzione dei sorgenti Python.

  • Ecco una semplice implementazione dei costruttori per date e orari basati su tick Unix che delegano il lavoro ai costruttori generici:
    import time
    
    def DateFromTicks(ticks):
    
        return apply(Date,time.localtime(ticks)[:3])
    
    def TimeFromTicks(ticks):
    
        return apply(Time,time.localtime(ticks)[3:6])
    
    def TimestampFromTicks(ticks):
    
        return apply(Timestamp,time.localtime(ticks)[:6])
    

  • Questa classe Python permette di implementare i tipi di oggetti summenzionati anche nel caso in cui il campo type_code dell'attributo description fornisce valori multipli per un oggetto Tipo:
    class DBAPITypeObject:
        def __init__(self,*values):
    	self.values = values
        def __cmp__(self,other):
    	if other in self.values:
    	    return 0
    	if other < self.values:
    	    return 1
    	else:
    	    return -1
    

    L'oggetto Tipo risultante eguaglia tutti i valori passati al costruttore.

  • Ecco un pezzetto di codice Python che implementa la gerarchia delle eccezioni definita in precedenza:
    import exceptions
    
    class Error(exceptions.StandardError):
        pass
    
    class Warning(exceptions.StandardError):
        pass
    
    class InterfaceError(Error):
        pass
    
    class DatabaseError(Error):
        pass
    
    class InternalError(DatabaseError):
        pass
    
    class OperationalError(DatabaseError):
        pass
    
    class ProgrammingError(DatabaseError):
        pass
    
    class IntegrityError(DatabaseError):
        pass
    
    class DataError(DatabaseError):
        pass
    
    class NotSupportedError(DatabaseError):
        pass
    

    In C si può usare l'API PyErr_NewException(fullname, base, NULL) per creare gli oggetti Eccezione.

Principali modifiche dall'API v.1.0

    L'API Python per i Database v.2.0 introduce un piccolo numero di cambiamenti importanti rispetto alla versione 1.0. Dato che alcuni di questi saranno causa di errori fatali negli script basati sulla vecchia DB API 1.0[off-site link], si è deciso di variare il numero di versione principale.

    Ecco i cambiamenti più significativi dalla versione 1.0:

    • Non è più necessario un modulo dbi separato, le sue funzionalità sono state fuse nell'interfaccia di modulo.

    • Sono stati aggiunti nuovi costruttori e oggetti Tipo per i valori di date e orari. Il tipo di oggetto RAW è stato rinominato come BINARY. L'insieme di tipi risultante dovrebbe coprire tutti i tipi di dato fondamentali che si trovano comunemente nei moderni database SQL.

    • Sono stati aggiunti nuove costanti (apilevel, threadlevel, paramstyle) e metodi (executemany, nextset) per garantire connessioni migliori ai database.

    • Le semantiche di .callproc() necessarie a chiamare stored procedure sono ora definite chiaramente.

    • La definizione del valore restituito da .execute() è stata cambiata. In precedenza il valore restituito era basato sul tipo di operazione SQL (difficile da implementare in modo soddisfacente). Ora il tipo non è definito, si usi piuttosto il più flessibile attributo .rowcount. I moduli sono liberi di restituire valori nel vecchio stile, ma le specifiche non se ne occupano più e dovrebbero essere considerati dipendenti dalle singole interfacce [e da non utilizzarsi nell'ottica di portabilità del codice NdT].

    • È stata incorporata nelle specifiche una gerarchia di eccezioni basata sulle classi. Gli implementatori del modulo sono liberi di estendere lo schema presentato in questo documento tramite sottoclassi.

Questioni ancora in sospeso

    Sebbene la versione 2.0 delle specifiche chiarisca molti punti ch'erano lasciati in sospeso nella versione 1.0, rimangono ancora delle questioni da affrontare:

  • Definire un valore di ritorno utile per .nextset() nel caso in cui un nuovo risultato sia effettivamente disponibile.

  • Creare un tipo numerico a virgola fissa da usare come formato di scambio senza sprechi per valori monetari e decimali.


Note a piè di pagina

  1. Come linea guida, i parametri del costruttore di oggetti Connessione dovrebbero essere implementati come argomenti a parola chiave per un uso più intuitivo, e seguire quest'ordine:

    dsn = Nome della sorgente dei dati come stringa
    user = Nome dell'utente come stringa (opzionale)
    password = Password come stringa (opzionale
    host = Nome dell'host (opzionale)
    database = Nome del database (opzionale)

    ecco un esempio di un tale uso di connect:

    connect(dsn='myhost:MYDB',user='guido',password='234$')

  2. Gli autori del modulo dovrebbero preferire i formati 'numeric', 'named' o 'pyformat' sugli altri, dato che offrono maggior chiarezza e flessibilità.

  3. Se il database non supporta la funzionalità richiesta dal metodo, l'interfaccia dovrebbe sollevare un'eccezione in caso venga invocato.

    L'approccio preferito è non implementare il metodo, in modo che Python generi un'eccezione AttributeError in caso di richiesta del metodo. Ciò permette al programmatore di verificare quanto può offrire il database usando la funzione standard hasattr().

    Per alcune interfacce configurate dinamicamente potrebbe non essere appropriato richiedere di rendere disponibile il metodo dinamicamente. Queste interfacce dovrebbero quindi sollevare un'eccezione NotSupportedError per indicare l'incapacità di eseguire il roll-back allorché il metodo venisse invocato.

  4. Un'interfaccia può scegliere di supportare i cursori con nome permettendo l'aggiunta di un argomento stringa al metodo. Questa caratteristica non viene contemplata nelle specifiche, dato che complicherebbe le semantiche dei metodi .fetchXXX().

  5. Il modulo userà il metodo __getitem__ degli oggetti dei parametri per mappare o le posizioni (interi) o i nomi (stringhe) dei valori dei parametri. Questo permette di accettare in ingresso sia sequenze che dizionari.

    Il termine "connesso" si riferisce al processo di connettere un valore in ingresso a un buffer di esecuzione del database. In termini pratici questo significa che il valore in ingresso è usato direttamente come valore in un'operazione. Al client non dovrebbe essere richiesto di dover proteggere il valore in modo che possa essere usato, esso dovrebbe infatti essere uguale al valore "reale" del database.

  6. Si noti che l'interfaccia potrebbe implementare il prelievo delle righe usando array e altre ottimizzazioni. Nulla garantisce che una chiamata a tale metodo muova il cursore associato in avanti di una sola riga.

  7. L'attributo rowcount può essere codificato in modo che aggiorni dinamicamente il proprio valore. Ciò può essere utile per database che restituiscono valori di rowcount utilizzabili solo dopo una prima chiamata al metodo .fetchXXX().