SQLObject e banco de dados legado
SqlObject tem um excelente suporte a banco de dados legado, e é o que preciso. Estou migrando umas aplicações para Python, elas usam Firebird e vão continuar usando. Problema: Além de um banco com nomes não elegantes para usar em objetos, tem hora que se usa generators para gerar IDs, outra hora usa-se procedures e por ai vai! Infelimente o Sqlobject OBRIGA a você ter um generator com o nome GEN_NOME_DA_TABELA. E eu preciso de outra maneira, então meti a mão na massa e alterei junto com um amigo a bibliteca, está aqui o Patch (Obviamente serviu para o meu caso, no seu eu não garanto!):
diff C3 C:/Python25/Lib/site-packages/SQLObject-0.9.1-py2.5.egg/sqlobject/firebird/firebirdconnection.py C:/Python25/Lib/site-packages/SQLObject-0.9.1-py2.5.egg/sqlobject/firebird/firebirdconnection_original.py
*** C:/Python25/Lib/site-packages/SQLObject-0.9.1-py2.5.egg/sqlobject/firebird/firebirdconnection.py Fri Aug 24 15:59:04 2007
--- C:/Python25/Lib/site-packages/SQLObject-0.9.1-py2.5.egg/sqlobject/firebird/firebirdconnection_original.py Thu Aug 16 10:39:08 2007
***************
*** 93,110 ****
sequenceName = soInstance.sqlmeta.idSequence or \
'GEN_%s' % table
c = conn.cursor()
! if id is None and soInstance.sqlmeta.idSequence is not None:
c.execute('SELECT gen_id(%s,1) FROM rdb$database'
% sequenceName)
id = c.fetchone()[0]
!
! if id is not None:
! names = [idName] + names
! values = [id] + values
! else:
! c.execute("SELECT cast(Max(%s) as integer) FROM %s WHERE 1=1" % (idName, table))
! id = int(c.fetchone()[0])+1
!
q = self._insertSQL(table, names, values)
if self.debug:
self.printDebug(conn, q, 'QueryIns')
--- 93,104 ----
sequenceName = soInstance.sqlmeta.idSequence or \
'GEN_%s' % table
c = conn.cursor()
! if id is None:
c.execute('SELECT gen_id(%s,1) FROM rdb$database'
% sequenceName)
id = c.fetchone()[0]
! names = [idName] + names
! values = [id] + values
q = self._insertSQL(table, names, values)
if self.debug:
self.printDebug(conn, q, 'QueryIns')
*Como se pode ver to usando windows para desenvolvimento, infelizmente… Solucionado o problema, agora vamos ver como conseguimos objetos elegantes com banco de dados nem tão elegantes assim. Entenda por não elegante um campo de uma tabela que se chama MENSAGENS, se chamar MSG_BODY ao invés de só BODY. Eu não gosto de criar siglas em campos.
# -*- coding: iso-8859-1-*-
from sqlobject import *
from pylons.database import PackageHub
import datetime
hub = PackageHub("XX_pylons")
__connection__ = hub
class Mensagem(SQLObject):
class sqlmeta:
table = "XX_MENSAGENS"
idName = "MSG_CODIGO"
subject = UnicodeCol(dbName='MSG_SUBJECT', dbEncoding="iso-8859-1", default='')
body = UnicodeCol(dbName='MSG_BODY', dbEncoding="iso-8859-1", default='')
status = IntCol(dbName='MSG_STATUS',default=0)
data = DateTimeCol(dbName='MSG_DATA',default=datetime.datetime.now())
para = ForeignKey('Usuario', dbName='USR_CODIGO_TO')
de = ForeignKey('Usuario', dbName='USR_CODIGO_FROM')
Como podemos ver eu setei o nome das colunas no banco que correspondem com meus atributos do objeto. Então o campo que se chama no banco USR_CODIGO_TO no objeto se chama para.
Bem mais elegante. Eu também falei que aquele objeto no banco corresponde a tabela XX_MENSAGENS e o campo que é ID é o MSG_CODIGO. Caso você use generators pode colocar o campo idSequence para o nome do seu generator (ele vai concatenar GEN_ antes no nome que você passar). Você pode ver mais sobre isso na página de documentação do SQLObject. Que está meio desatualizada então vá ao TRAC deles também. Embora eles ainda indiquem a maneira antiga de se trabalar com banco de dados legado. Essas dicas que passei servem tmbém para qualquer outro banco, inclusive Mysql.
Para finalizar eu queria pedir encarecidamente que os DBAs por ai usem generators e com nomes padronizados!