[Python] Concatenazione lato DB => Rebus

Simone Federici s.federici a gmail.com
Mer 21 Mar 2012 13:09:48 CET


2012/3/20 Stefano Dal Pra <s.dalpra a gmail.com>

> Non so se ho capito bene cosa ti serve, ma con questo:
>
> keys = [
>     ("LDAP server", "Agent"),
>     ("-LDAP-server-", "_S-"),
>     ("Pippo'", "'pluto"),
>      ("Pippo", None),
>     ("Pippo", "")
> ]
>
> T=[]
> for a,b in keys:
>     print q.curs.mogrify("select trim(%s|| coalesce( '_'||%s,''
> ),'_');",(a,b))
>     q.curs.execute("select trim(%s|| coalesce( '_'||%s,'' ),'_');",(a,b))
>     T.append(q.curs.fetchone()[0])
>
> print '\n'.join(T)
>
>
> Ottengo:
> >>> T=[]
> >>> for a,b in keys:
> ...     print q.curs.mogrify("select trim(%s|| coalesce( '_'||%s,''
> ),'_');",(a,b))
> ...     q.curs.execute("select trim(%s|| coalesce( '_'||%s,''
> ),'_');",(a,b))
> ...     T.append(q.curs.fetchone()[0])
> ...
> select trim('LDAP server'|| coalesce( '_'||'Agent','' ),'_');
> select trim('-LDAP-server-'|| coalesce( '_'||'_S-','' ),'_');
> select trim('Pippo'''|| coalesce( '_'||'''pluto','' ),'_');
> select trim('Pippo'|| coalesce( '_'||NULL,'' ),'_');
> select trim('Pippo'|| coalesce( '_'||'','' ),'_');
> >>> print '\n'.join(T)
> LDAP server_Agent
> -LDAP-server-__S-
> Pippo'_'pluto
> Pippo
> Pippo
>
> Ciao
> Stefano
>


Ciao Stefano,

cerco di essere più chiaro

SELECT NAME, AUTHOR FROM BOOK;

sono 2 campi della tabella book, ma non sono semplici campi sono la primary
key composta della tabella book.

ora, in django non è possibile fare una cosa del genere a meno che di
aggiungere una ulteriore colonna ID auto increment e fregarsene che la
tabella è relazionata cosi.

Chiaramente se dovessi modellare tu il database la tabella chapters la
metteresti con una ForeignKey verso la colonna ID della tabella book, ma...
se il db è di una aplpicazione già fatta che non puoi toccare?

è qui che entra il progetto che stò scrivendo che ha lo scopo di dare la
possibilità di usare chiavi composte usando i modelli django.

quindi di fatto la tabella chapter avrà 2 colonne book_author e boor_name
che identificano la relazione book->chapters.


Ora, fino qui è facile, e anche gestire lato python la cosa è facile, il
casino viene quando confrontiamo questa realtà con il concetto di relazioni
generiche di django, dove una qualsiasi tabella, admin logs, tagging,
messages, threads, possono essere legate a un QUALSIASI modello.

Quindi si usa una relazione datta fa ContentType e content_id. Dove il
content_id è la chiave della tabella.

Nell'esempio book, name e author sono entrambe parti della chiave, quindi
cosa ci sriviamo nella tabella che ha una rel generica? (ad esempio quella
dei tags)

in prima battuta c'ho messo una concatenazione lato python delle chiavi
univoche, e ho realizzato la librerie. Funziona in tutto e per tutto tranne
in una funzionalità, ossia "dammi tutti i tags relazionati a questi
oggetti", che avviene tramite una SELECT che mette in join la tabella book
con la tabella tags.

Chiaramente visto che la chiave l'ho calcolata con python, non sono ingrado
di fare una join e quindi prima mi devo prendere tutte le chiavi, poi devo
produrre le concatenazioni e infine devo fare la queri con select in [pks].
COMPLETAMENTE NON PERFORMANTE

Quindi di fattos to cercando un modo di avere una funzione python che sia
ingrado di fare la concatenazione e il contrario, ma che abbia una sua
implementazione (almeno la concatenazione) lato DATABASE.

Cross database, quindi sia SQLITE, PGSQL, ORACLE, MYSQL (etc...)

Quindi la domanda riguarda la sintassi SQL non la sintassi python.
Comunque la soluzione che proponi purtroppo non è univoca, perche manca del
quoting delle colonne altrimenti non potremmo distinguere

-LDAP-server-__S-
=>
( "-LDAP-server-", "", "_S-" )
( "-LDAP-server-", "", "", "S-" )
( "-LDAP-server-", "_", "S-" )

per questo nella concatenazione c'è bisogno di fare il quoting con apice
singolo delle colonne e anche l'escaping sempre dell'apice singolo.

'-LDAP-server-'_'_S-'
da notare che qui i 2 underscore sono di facile comprensione, uno è unn
separatore, l'altro è parte della contenuto, basta contare il numero di
apici alla sua sinistra se è pari è un separatore.

ciao
Simone
-------------- parte successiva --------------
Un allegato HTML è stato rimosso...
URL: <http://lists.python.it/pipermail/python/attachments/20120321/9b91899e/attachment.html>


Maggiori informazioni sulla lista Python