Thread: Re: [SQLObject] FW: longId=True handling...
SQLObject is a Python ORM.
Brought to you by:
ianbicking,
phd
From: Joe L. <joe...@gm...> - 2009-06-11 14:11:41
|
This issue seems to be caused by a change in SQLObject. The change in behaviour seems to be due to a change made in SQLObject in main.py, where the ‘idName’ attribute was taken out of a list of unshared attributes. This caused the sqlmeta class to share the idName value with its containing class, so they both end up with ‘id’ even when longID is set to true in your own class. If you add it back in: _unshared_attributes = ['table', 'columns', 'childName', 'idName'] then it should work as before...however, I'm not sure if this will cause other problems (so far it seems to work). It seems that the longID feature is broken unless this little change is made. OR, are we misunderstanding the "new" way to make longID work properly? By the way, here is a link to a change that seems to have triggered this change in behaviour: http://www.mail-archive.com/sql...@li.../msg02159.html Joe > > > *From:* Sam's Lists [mailto:sam...@gm...] > *Sent:* Wednesday, June 10, 2009 9:06 PM > *To:* sqlobject-discuss > *Subject:* [SQLObject] longId=True handling... > > > > I posted this on the TurboGears mailing list but now I'm posting it here in > hopes for more help. > > Essentially I am upgrading from SQLObject 0.7.1dev_r1653 and MySQL 4.x > something to MySQL 5 something and SQLObject 0.10.6 > > I have this very complicated legacy TurboGears application that I'm > tasked with upgrading to 1.0.8 which has laid stagnant since the days > of early .99 series. > > The original author used the following a lot in his table definitions: > > class sqlmeta: > style = MixedCaseStyle(longID=True) > > What this means is that instead of the id column being named 'id' it > takes on the name of the table...so if the table is called EventQueue, > the id column name is EventQueueID. > > So far so good....but here's where it gets weird. > > It appears that under the really old versions of TurboGears one could > refer to this EventQueueID as just .id and everything would work the > way you want it to. (This appears to only be done in the app under > kid templates). > > But now, under TG 1.0.8/the latest version of SQLObject that doesn't work. > Either I have to rename the > column to id or I have to refer to it as EventQueueID. > > How can I make sqlObject seemlessly let me refer to columns named in > the long style just using id? > > Thanks > > > |
From: Oleg B. <ph...@ph...> - 2010-01-22 18:57:32
|
Hello! I returned to investigate the issue and found it's more complex than I thought... On Thu, Jun 11, 2009 at 10:11:27AM -0400, Joe Lanese wrote: > This issue seems to be caused by a change in SQLObject. > The change in behaviour seems to be due to a change made in SQLObject in > main.py, where the ?idName? attribute was taken out of a list of unshared > attributes. This caused the sqlmeta class to share the idName value with > its containing class, so they both end up with ?id? even when longID is set > to true in your own class. If you add it back in: > _unshared_attributes = ['table', 'columns', 'childName', 'idName'] > then it should work as before...however, I'm not sure if this will cause > other problems (so far it seems to work). > > By the way, here is a link to a change that seems to have triggered this > change in behaviour: > http://www.mail-archive.com/sql...@li.../msg02159.html In essence, the problem is in class sqlmeta, method setClass: if cls.idName is None: cls.idName = cls.style.idForTable(cls.table) The method poises the class so in any class inherited from sqlmeta idName will be already set and the test fails. Adding idName to the list of unshared attributes resets idName to None but that prevents proper inheritance of idName. To explain all this with code - with current SQLObject the following code class sqlmeta(sqlmeta): idName = 'ddd' class Test1(SQLObject): class sqlmeta(sqlmeta): style = MixedCaseStyle(longID=True) Test1.createTable() print Test1.sqlmeta.idName class Test2(SQLObject): class sqlmeta: style = MixedCaseStyle(longID=True) Test2.createTable() print Test2.sqlmeta.idName prints 'ddd' and 'id'; the first idName is right and the second one is wrong (it must be 'Test2ID'). The same code running with idName added to the list of unshared attributes prints 'Test1ID' and 'Test2ID'; the first one is wrong (it must be 'ddd') and the second one is right. Probably the correct way of fixing it is to add idName (and 'style' because setClass tests and sets it too) to the list of unshared attributes but make sqlmeta.__classinit__ to recognize inherited attributes and do not reset them. I will think of it... Oleg. -- Oleg Broytman http://phd.pp.ru/ ph...@ph... Programmers don't die, they just GOSUB without RETURN. |
From: Oleg B. <ph...@ph...> - 2010-01-25 17:49:24
|
On Fri, Jan 22, 2010 at 09:57:13PM +0300, Oleg Broytman wrote: > In essence, the problem is in class sqlmeta, method setClass: > > if cls.idName is None: > cls.idName = cls.style.idForTable(cls.table) > > The method poisons the class so in any class inherited from sqlmeta idName > will be already set and the test fails. > Adding idName to the list of unshared attributes resets idName to None > but that prevents proper inheritance of idName. > To explain all this with code - with current SQLObject the following > code > > class sqlmeta(sqlmeta): > idName = 'ddd' > > class Test1(SQLObject): > class sqlmeta(sqlmeta): > style = MixedCaseStyle(longID=True) > > print Test1.sqlmeta.idName > > class Test2(SQLObject): > class sqlmeta: > style = MixedCaseStyle(longID=True) > > print Test2.sqlmeta.idName > > prints 'ddd' and 'id'; the first idName is right and the second one is > wrong (it must be 'Test2ID'). > The same code running with idName added to the list of unshared attributes > prints 'Test1ID' and 'Test2ID'; the first one is wrong (it must be 'ddd') > and the second one is right. > Probably the correct way of fixing it is to add idName (and 'style' > because setClass tests and sets it too) to the list of unshared attributes > but make sqlmeta.__classinit__ to recognize inherited attributes and do not > reset them. I will think of it... Well, instead of trying to find what was inherited and what was set in parent's setClass() I just prevented setClass() from poisoning the base sqlmeta. The patch is just Index: sqlobject/main.py =================================================================== --- sqlobject/main.py (revision 4089) +++ sqlobject/main.py (working copy) @@ -853,7 +853,8 @@ del values[key] cls.sqlmeta = type('sqlmeta', (superclass,), values) - cls.sqlmeta.setClass(cls) + if not is_base: # Do not pollute the base sqlmeta class + cls.sqlmeta.setClass(cls) _SO_setupSqlmeta = classmethod(_SO_setupSqlmeta) With the patch the code above prints 'ddd' and 'Test2ID' which is exactly right. The test suite passed so if nobody reports any problem with the patch I will apply it to the trunk. Oleg. -- Oleg Broytman http://phd.pp.ru/ ph...@ph... Programmers don't die, they just GOSUB without RETURN. |