Tg1 is doing something weird when it encounters python inheritance in
an sqlobject model schema.
The following works perfectly in sqlobject, forgetting tg for a second:
###########################################################
from sqlobject import SQLObject
from sqlobject import StringCol
class data(SQLObject):
item = StringCol( )
class deleted_data(data):
time = DateTimeCol( )
###########################################################
The idea is to copy all fields from data to deleted_data and add some
more to deleted_data. This is described in
http://www.sqlobject.org/FAQ.html#how-does-inheritance-work
So I'd like to have a similar pattern in tg1. So I put the following
into my freshly quickstarted model.py:
###########################################################
from turbogears.database import PackageHub
from sqlobject import SQLObject
from sqlobject import StringCol, UnicodeCol, IntCol, DateTimeCol
__connection__ = hub = PackageHub('mytest')
class data(SQLObject):
item = StringCol( )
class deleted_data(data):
time = DateTimeCol( )
############################################################
Now, when I try to import model.py in a python session, it fails:
Python 2.5.1 (r251:54863, Oct 30 2007, 13:45:26)
[GCC 4.1.2 20070925 (Red Hat 4.1.2-33)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import model
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "model.py", line 11, in <module>
class deleted_data(data):
File "/usr/lib/python2.5/site-packages/SQLObject-0.10.4-py2.5.egg/sqlobject/declarative.py",
line 92, in __new__
cls.__classinit__(cls, new_attrs)
File "/usr/lib/python2.5/site-packages/SQLObject-0.10.4-py2.5.egg/sqlobject/main.py",
line 761, in __classinit__
if not connection and not getattr(cls, '_connection', None):
File "/usr/lib/python2.5/site-packages/TurboGears-1.1b3-py2.5.egg/turbogears/database.py",
line 297, in __get__
self.set_hub()
File "/usr/lib/python2.5/site-packages/TurboGears-1.1b3-py2.5.egg/turbogears/database.py",
line 315, in set_hub
raise KeyError, "No database configuration found!"
KeyError: 'No database configuration found!'
Note that I don't want to insert anything into the database, I know
that in order to do that (i.e. use the model outside of tg), I need to
follow http://docs.turbogears.org/1.0/ModelOutsideTG
Here I'm merely importing the module and it fails.
Naturally, if the python inheritance is left out, i.e. I have the
following in model.py
#############################################################
from turbogears.database import PackageHub
from sqlobject import SQLObject
from sqlobject import StringCol, UnicodeCol, IntCol, DateTimeCol
__connection__ = hub = PackageHub('mytest')
class data(SQLObject):
item = StringCol( )
# class deleted_data(data):
# time = DateTimeCol( )
#############################################################
I can import model in a python session:
Python 2.5.1 (r251:54863, Oct 30 2007, 13:45:26)
[GCC 4.1.2 20070925 (Red Hat 4.1.2-33)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import model
>>>
So it seems tg1 is trying to do something that is not really necessary
since I don't want to insert anything into the db, I don't want to use
it in any way, I just would like to import it.
Any ideas what's going on? Should I file a ticket?
Cheers,
Daniel
--
Psss, psss, put it down! - http://www.cafepress.com/putitdown
This happens in all TG 1.x versions.
The problem here is that during the class initialization of the
subclass, its "_connection" attribute is checked by fetching it, and
since its is already set (to the PackageHub instance) by the parent
class, the PackageHub tries to get the real connection which fails.
You get the same error without any inheritance, if you just do:
##########################################
from turbogears.database import PackageHub
from sqlobject import SQLObject, StringCol
__connection__ = PackageHub('mytest')
class data(SQLObject):
item = StringCol()
print data._connection
##########################################
Accessing the _connection as attribute causes the __get__ method of the
PackageHub to be called which tries to get the real connection.
A simple fix is changing the __get__ method of the PackageHub class in
turbogears.database to something like this:
def __get__(self, obj, type):
try:
if not self.hub:
self.set_hub()
except Exception:
# cannot get real hub, return proxy only
return self
else:
return self.hub.__get__(obj, type)
However, I'm not using SQLObject, so I'd like to get some feedback from
SQLObject users before changing this in TG 1.x.
-- Christoph
I've tested my code (using tg 1.1b3, sqlobject 0.10.4) and it works.
Thanks for the fix!
Ok, this is ticket #2160 now; I'll wait for some more feedback before
checking it in.
-- Christoph