[Python] psycopg2 e bytea

Stefano Dal Pra s.dalpra a gmail.com
Mer 16 Feb 2011 17:23:00 CET


Scusa, mi e' partito un send a vuoto sfiorando la tastiera; non so come sia
successo...
Magari riscrivo meglio appena posso.
Ciao e scusa il disguido
Stefano

2011/2/16 Stefano Dal Pra <s.dalpra a gmail.com>

>
>
> 2011/2/16 Daniele Varrazzo <piro a develer.com>
>
> On Wed, 16 Feb 2011 16:13:16 +0100, Stefano Dal Pra <s.dalpra a gmail.com>
>> wrote:
>> > Ciao Daniele, credo che un problema analogo valga anche per i boolean in
>> > postgres.
>> >
>> > Sto migrando un db mysql in uno equivalente postgres.
>> > faccio sostanzialmente cose tipo:
>> >
>> > mysqlcurs.execute("select * from Tab")
>> > T = mysqlcurs.fetchall() #ci stanno, ci stanno... :-)
>> > ...
>> > fms = ','.join("%s" for x in range(len(T[0])))
>> > for tup in T:
>> >     pg.curs.execute("insert into %s values (%s)"%(tablename,fms),tup)
>> >
>> >
>> > mysqldump mappa false/true in 0/1, per cui
>> > psycopg2.execute("insert into T (boolvalue) values (%s)",1)
>> > da errore (TypeError se ricordo bene?).
>>
>> No, questo TypeError viene dal fatto che in questo esempio hai usato "1" e
>> non una sequenza per passare gli argomenti.
>>
>
>
> insomma passo una tupla come si deve.
>
> Quel che mi chiedo io e': dopo un connect psycopg2 conosce tipi di dato
delle tabelle in cui va ad inserire?
Se cosi' fosse pensare ad un

>
>
>
>> Strano che postgres non converta valori numerici 1/0 in booleani, ma
>> confermo che è così:
>>
>>    In [10]: cur.execute("create table testbool (x bool);")
>>
>>    In [11]: cur.execute("insert into  testbool values (%s), (%s), (%s);",
>> (1,0,None))
>>
>>
>> ---------------------------------------------------------------------------
>>    ProgrammingError                          Traceback (most recent call
>> last)
>>
>>    /home/piro/src/psycopg2/<ipython console> in <module>()
>>
>>    ProgrammingError: column "x" is of type boolean but expression is of
>> type integer
>>    LINE 1: insert into  testbool values (1), (0), (NULL);
>>                                          ^
>>    HINT:  You will need to rewrite or cast the expression.
>>
>> È strano perchè quando viene forzato a fare un cast esplicito non ha
>> problemi:
>>
>>    In [12]: cur.execute("insert into  testbool values (%s::bool),
>> (%s::bool), (%s::bool);", (1,0,None))
>>
>>    In [13]: cur.execute("select * from testbool;")
>>
>>    In [14]: cur.fetchall()
>>    Out[14]: [(True,), (False,), (None,)]
>>
>> Un cast in postgres c'è, ma non è "implicito". Non saprei perché.
>>
>>
>> > Al momento risolvo la cosa con un dizionario:
>> > dbool = {0:False,1:True,None:None}
>> > (nota che bool(None) --> False, che per i db non va bene)
>> > e rimappando i campi boolean prima di inserirli...
>>
>> Mi sembra una buona soluzione. Quella analoga al caso dei bytea
>> consisterebbe nel wrappare i bool (e non tutti gli interi)... anche se
>> esistesse questo adapter (sarebbe facile da scrivere) non darebbe nessun
>> vantaggio rispetto al mapping.
>>
>> Una soluzione alternativa sarebbe quella di identificare quali sono i
>> campi booleani e usare dei cast dopo i segnaposto come nella [12]. Puoi
>> addirittura chiedere automaticamente a postgres quali siano i campi bool
>> nella tua tabella:
>>
>>    In [21]: cur.execute("create table stuff (foo int, bar bool, baz
>> text);")
>>
>>    In [22]: cur.execute("select * from stuff limit 0")
>>
>>    In [23]: cur.description
>>    Out[23]:
>>    (('foo', 23, None, 4, None, None, None),
>>     ('bar', 16, None, 1, None, None, None),
>>     ('baz', 25, None, -1, None, None, None))
>>
>> I campi di tipo 16 sono i bool: puoi generare placeholder col cast da
>> questa informazione:
>>
>>    In [25]: ",".join(t[1] == 16 and "%s::bool" or "%s" for t in
>> cur.description)
>>    Out[25]: '%s,%s::bool,%s'
>>
>>
>> > Versioni + recenti di psycopg2 si comportano diversamente in questo
>> caso?
>>
>> No: il cast in sql viene scelto in base al tipo: se mysql passa un integer
>> sia per interi che per bool, python non fa distinzione di tipo tra i due e
>> psycopg usa lo stesso mapping per entrambi.
>>
>>
>> --
>> Daniele Varrazzo - Develer S.r.l.
>> http://www.develer.com
>> _______________________________________________
>> Python mailing list
>> Python a lists.python.it
>> http://lists.python.it/mailman/listinfo/python
>>
>
>
-------------- parte successiva --------------
Un allegato HTML è stato rimosso...
URL: <http://lists.python.it/pipermail/python/attachments/20110216/6115f0e5/attachment-0001.html>


Maggiori informazioni sulla lista Python