[Python] O non capisco sqlite, o non capisco sqlalchemy, o entrambi

Daniele Varrazzo piro a develer.com
Mar 19 Nov 2013 19:50:50 CET


On 2013-11-19 17:58, Pietro Battiston wrote:
> Il giorno mar, 19/11/2013 alle 17.55 +0100, Manlio Perillo ha 
> scritto:
>> On 19/11/2013 17:30, Pietro Battiston wrote:
>> > [...]
>> >> oppure:
>> >> for row in r:
>> >>      print row['id'], row['rel']
>> >
>> >
>> > Sì, questo mi è chiaro, ma a me piace più un
>> >
>> >      print mio_ogg.id, mio_ogg.rel
>> >
>>
>> La differenza tra
>>
>>         print row['id'], row['rel']
>>
>> è solo di "facciata", specialmente se tieni conto che, in realtà, 
>> quello
>> che tu hai scritto è equivalente, in Python, a:
>>
>>         print mio_ogg.__dict__['id'], mio_ogg.__dict__['rel']
>
>
> Sì, sì, certo! Ti sto solo dicendo quale facciata preferisco...

L'interfaccia di quello che ottieni in Python (row.id, row.rel) è 
indipendente dagli strati sottostanti (usare o meno un orm). Puoi avere 
un driver che fa una query e restituisce un oggetto con gli attributi 
(es. psycopg2 con i NamedTupleCursor lo fa). Scrivere un wrapper che 
converte tuple/dizionari in oggetti è banale, molto più di un ORM.


>> > ... a te no?! Perché se sto parlando di utenti e loro 
>> informazioni, di
>> > città e loro posizioni, e più in generale di oggetti e loro 
>> proprietà,
>> > dovrei scrivere di righe e loro elementi?!
>> >
>>
>> Perchè è quello che realmente sono, visto che sono memorizzati in un
>> database relazionale.
>
> ... ma mi piacciono le facciate! Ovviamente, non tanto da sacrificare
> l'efficienza.

Usando una facciata senza sapere cosa c'è dietro il più delle volte la 
sacrifica, l'efficienza.



>> > [...]
>> > Appunto... e anche nei casi in cui (poniamo) non ho tabelle 
>> collegate,
>> > con l'ORM la classe me la definisco io,
>>
>> Perchè, la tabella SQL no?
>>
>
> Beh, sì... ma se non sbaglio il python è un linguaggio ad oggetti, 
> non a
> tabelle :-)

Python non è integralista di alcun paradigma specifico. Ha anche 
funzioni che non sono metodi di oggetti: che fai, quelle non le usi 
perché è "a oggetti"?

Pensare che tutto sia un oggetto è una limitazione molto pesante nel 
contesto dei database. Tanto per buttarla lì: "quanti ordini ho evaso 
ieri?". "ci sono ordini inevasi più vecchi di una settimana"? Sono 
esempi di domande che non hanno bisogno di modellare l'ordine nella sua 
interezza. Usare un ORM per questo tipo di richieste produce query 
inefficienti.


>> > posso aggiungerle dei metodi che
>> > mi servono,
>>
>> Puoi anche definire funzioni libere, che operano sulla tuple (perchè
>> tanto in Python i metodi sono funzioni libere, alla fine).
>
> ... ci deve essere davvero qualcosa di grosso che mi sfugge se, 
> mentre
> cerco di organizzare il mio codice in ordinate classi, un veterano 
> (del
> Vietnam? ;-) ) mi dice che in Python posso "anche definire funzioni
> libere"...

OOP non vuol dire automaticamente buon design, soprattutto quando il 
problema non è inerentemente ad oggetti. E ORM non vuol dire 
automaticamente buon design, se in ambienti diversi (il codice e la base 
dati) il dominio si modella bene in maniera diversa. Dire "uso le classi 
quindi sto facendo bene" è più "ad una persona col martello ogni 
problema sembra un chiodo".

(per completezza cito anche JWZ: "once those database worms eat into 
your brain, it's hard to ever get anything practical done again. To a 
database person, every nail looks like a thumb. Or something like that")


> Quello che mi incuriosiva era solo lo step successivo, "evita ORM se
> possibile"... e ora dovrei avere di che riflettere.

Prego, rifletti pure. Ma fallo a mente aperta: se parti dai paradigmi

1. tutto è un oggetto
2. nel db ci sono solo oggetti

ovviamente arriverai alla conclusione che gli ORM sono l'invenzione 
migliore dopo il pane affettato. Prova con:

1. far diventare tutto un oggetto non è sempre utile
2. il modello relazionale è un soprainsieme del modello degli oggetti

e vedi come va.


-- Daniele



Maggiori informazioni sulla lista Python