<br><br><div class="gmail_quote">2011/2/16 Daniele Varrazzo <span dir="ltr"><<a href="mailto:piro@develer.com">piro@develer.com</a>></span><br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
On Wed, 16 Feb 2011 16:13:16 +0100, Stefano Dal Pra <<a href="mailto:s.dalpra@gmail.com">s.dalpra@gmail.com</a>><br>
wrote:<br>
<div class="im">> Ciao Daniele, credo che un problema analogo valga anche per i boolean in<br>
> postgres.<br>
><br>
> Sto migrando un db mysql in uno equivalente postgres.<br>
> faccio sostanzialmente cose tipo:<br>
><br>
> mysqlcurs.execute("select * from Tab")<br>
> T = mysqlcurs.fetchall() #ci stanno, ci stanno... :-)<br>
> ...<br>
> fms = ','.join("%s" for x in range(len(T[0])))<br>
> for tup in T:<br>
> pg.curs.execute("insert into %s values (%s)"%(tablename,fms),tup)<br>
><br>
><br>
> mysqldump mappa false/true in 0/1, per cui<br>
> psycopg2.execute("insert into T (boolvalue) values (%s)",1)<br>
> da errore (TypeError se ricordo bene?).<br>
<br>
</div>No, questo TypeError viene dal fatto che in questo esempio hai usato "1" e<br>
non una sequenza per passare gli argomenti.<br></blockquote><div><br>Scusami, purtroppo ho scritto "a memoria" invece di fare un sano cut&paste.<br>Quello che faccio equivale in realta' al test che hai messo tu:<br>
cur.execute("insert into testbool values (%s), (%s), (%s);",<br>
(1,0,None))<br><br>insomma passo una tupla come si deve.<br><br>Quel che mi chiedo io e':<br>se dopo un connect psycopg2<br><br><br></div><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
<br>
Strano che postgres non converta valori numerici 1/0 in booleani, ma<br>
confermo che è così:<br>
<br>
In [10]: cur.execute("create table testbool (x bool);")<br>
<br>
In [11]: cur.execute("insert into testbool values (%s), (%s), (%s);",<br>
(1,0,None))<br>
<br>
---------------------------------------------------------------------------<br>
ProgrammingError Traceback (most recent call<br>
last)<br>
<br>
/home/piro/src/psycopg2/<ipython console> in <module>()<br>
<br>
ProgrammingError: column "x" is of type boolean but expression is of<br>
type integer<br>
LINE 1: insert into testbool values (1), (0), (NULL);<br>
^<br>
HINT: You will need to rewrite or cast the expression.<br>
<br>
È strano perchè quando viene forzato a fare un cast esplicito non ha<br>
problemi:<br>
<br>
In [12]: cur.execute("insert into testbool values (%s::bool),<br>
(%s::bool), (%s::bool);", (1,0,None))<br>
<br>
In [13]: cur.execute("select * from testbool;")<br>
<br>
In [14]: cur.fetchall()<br>
Out[14]: [(True,), (False,), (None,)]<br>
<br>
Un cast in postgres c'è, ma non è "implicito". Non saprei perché.<br>
<div class="im"><br>
<br>
> Al momento risolvo la cosa con un dizionario:<br>
> dbool = {0:False,1:True,None:None}<br>
> (nota che bool(None) --> False, che per i db non va bene)<br>
> e rimappando i campi boolean prima di inserirli...<br>
<br>
</div>Mi sembra una buona soluzione. Quella analoga al caso dei bytea<br>
consisterebbe nel wrappare i bool (e non tutti gli interi)... anche se<br>
esistesse questo adapter (sarebbe facile da scrivere) non darebbe nessun<br>
vantaggio rispetto al mapping.<br>
<br>
Una soluzione alternativa sarebbe quella di identificare quali sono i<br>
campi booleani e usare dei cast dopo i segnaposto come nella [12]. Puoi<br>
addirittura chiedere automaticamente a postgres quali siano i campi bool<br>
nella tua tabella:<br>
<br>
In [21]: cur.execute("create table stuff (foo int, bar bool, baz<br>
text);")<br>
<br>
In [22]: cur.execute("select * from stuff limit 0")<br>
<br>
In [23]: cur.description<br>
Out[23]:<br>
(('foo', 23, None, 4, None, None, None),<br>
('bar', 16, None, 1, None, None, None),<br>
('baz', 25, None, -1, None, None, None))<br>
<br>
I campi di tipo 16 sono i bool: puoi generare placeholder col cast da<br>
questa informazione:<br>
<br>
In [25]: ",".join(t[1] == 16 and "%s::bool" or "%s" for t in<br>
cur.description)<br>
Out[25]: '%s,%s::bool,%s'<br>
<div class="im"><br>
<br>
> Versioni + recenti di psycopg2 si comportano diversamente in questo<br>
caso?<br>
<br>
</div>No: il cast in sql viene scelto in base al tipo: se mysql passa un integer<br>
sia per interi che per bool, python non fa distinzione di tipo tra i due e<br>
psycopg usa lo stesso mapping per entrambi.<br>
<font color="#888888"><br>
<br>
--<br>
</font><div><div></div><div class="h5">Daniele Varrazzo - Develer S.r.l.<br>
<a href="http://www.develer.com" target="_blank">http://www.develer.com</a><br>
_______________________________________________<br>
Python mailing list<br>
<a href="mailto:Python@lists.python.it">Python@lists.python.it</a><br>
<a href="http://lists.python.it/mailman/listinfo/python" target="_blank">http://lists.python.it/mailman/listinfo/python</a><br>
</div></div></blockquote></div><br>