2011/2/16 Daniele Varrazzo <p...@develer.com> > On Wed, 16 Feb 2011 16:13:16 +0100, Stefano Dal Pra <s.dal...@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. >
Scusami, purtroppo ho scritto "a memoria" invece di fare un sano cut&paste. Quello che faccio equivale in realta' al test che hai messo tu: cur.execute("insert into testbool values (%s), (%s), (%s);", (1,0,None)) insomma passo una tupla come si deve. Quel che mi chiedo io e': se dopo un connect psycopg2 > 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@lists.python.it > http://lists.python.it/mailman/listinfo/python >
_______________________________________________ Python mailing list Python@lists.python.it http://lists.python.it/mailman/listinfo/python