Warning: Can't synchronize with repository "(default)" (Unsupported version control system "svn": No module named svn). Look in the Trac log for more information.

Ticket #1412 (closed defect: fixed)

Opened 10 years ago

Last modified 8 years ago

SQLObject Model Breaks Catwalk

Reported by: Cerin Owned by: chrisz
Priority: normal Milestone: 1.0.x bugfix
Component: Toolbox.Catwalk Version: 1.0.4b1
Severity: normal Keywords: needs patch, CatWalk, joinColumn
Cc:

Description

I used quickstart to setup a basic app with identity, and then I added two more classes to model.py. One has a foreign key to the Users class, and for some reason this is breaking Catwalk. I can't view the Users table, or add records to the other tables. Python produces the following traceback:

Traceback (most recent call last):

File "/usr/lib/python2.5/site-packages/CherryPy-2.2.1-py2.5.egg/cherrypy/_cphttptools.py", line 105, in _run

self.main()

File "/usr/lib/python2.5/site-packages/CherryPy-2.2.1-py2.5.egg/cherrypy/_cphttptools.py", line 254, in main

body = page_handler(*virtual_path, self.params)

File "<string>", line 3, in index File "/usr/lib/python2.5/site-packages/TurboGears-1.0.2.2-py2.5.egg/turbogears/controllers.py", line 336, in expose

*args, kw)

File "<string>", line 5, in run_with_transaction File "/usr/lib/python2.5/site-packages/TurboGears-1.0.2.2-py2.5.egg/turbogears/database.py", line 303, in so_rwt

retval = func(*args, kw)

File "<string>", line 5, in _expose File "/usr/lib/python2.5/site-packages/TurboGears-1.0.2.2-py2.5.egg/turbogears/controllers.py", line 351, in <lambda>

mapping, fragment, args, kw)))

File "/usr/lib/python2.5/site-packages/TurboGears-1.0.2.2-py2.5.egg/turbogears/controllers.py", line 378, in _execute_func

output = errorhandling.try_call(func, *args, kw)

File "/usr/lib/python2.5/site-packages/TurboGears-1.0.2.2-py2.5.egg/turbogears/errorhandling.py", line 73, in try_call

return func(self, *args, kw)

File "/usr/lib/python2.5/site-packages/TurboGears-1.0.2.2-py2.5.egg/turbogears/toolbox/catwalk/browse.py", line 24, in index

total,rows = self.rows_for_model(object_name,start,page_size,filters)

File "/usr/lib/python2.5/site-packages/TurboGears-1.0.2.2-py2.5.egg/turbogears/toolbox/catwalk/browse.py", line 124, in rows_for_model

relations = self.relation_values(object_name,rows)

File "/usr/lib/python2.5/site-packages/TurboGears-1.0.2.2-py2.5.egg/turbogears/toolbox/catwalk/browse.py", line 145, in relation_values

column.soClass.q.id==self.join_foreign_key(column),

File "/usr/lib/python2.5/site-packages/TurboGears-1.0.2.2-py2.5.egg/turbogears/toolbox/catwalk/browse.py", line 197, in join_foreign_key

return getattr(column.otherClass.q,foreign_key)

File "/usr/lib/python2.5/site-packages/SQLObject-0.9.0-py2.5.egg/sqlobject/sqlbuilder.py", line 381, in getattr

raise AttributeError?("%s instance has no attribute '%s'" % (self.soClass.name, attr))

AttributeError?: Viewing instance has no attribute 'tgID'

Attachments

modelbug.tar.gz Download (91.8 KB) - added by Cerin 10 years ago.
Sample app created by "tg-admin quickstart" that reproduces the error.

Change History

Changed 10 years ago by Cerin

Sample app created by "tg-admin quickstart" that reproduces the error.

comment:1 Changed 10 years ago by faide

  • Milestone changed from 1.0.3 to 1.1

comment:2 Changed 10 years ago by dUc0N

  • Keywords CatWalk, joinColumn added
  • Component changed from TurboGears to Toolbox.Catwalk

23JUN07 at 21:35 CEDT:

I don't have a fix... but I do have a workaround. It seems that this error is caused by CatWalk improperly handling joinColumn arguments in model.py, where if the argument supplied is "joinColumn='foo'", CatWalk will look for a column named 'fooID'. The easiest way to get around it is to use CatWalk's built in methods to get the same result. For example:

I have a table named Person, and another named City. When looking at the table in CatWalk, I'd much rather see people's names, and their city names, than the default behavior, which is to see the numeric IDs. Rather than list my City class in Model.py as:

class City(SQKObject):
    name = UnicodeCol(length=64)
    people = MultipleJoin("Person", joinColumn='name')

it's better to leave the joinColumn entirely out of the MultipleJoin. Then, to get the same effect from CatWalk, you can go to the class linking to it (in this case we want to go to the Person class). Find the ForeignKey item in the structure, and it should list the name of the object and column that are linked (here, it'd read: "City [city] SOForeignKey:City, label column:id".) You'll see "id" is hyperlinked. Click it, and you're presented with a dropdown menu to select any column from the City class. Pick the appropriate one for your app (in our example, "name"), and you've got the same end effect. Browsing the Person class from inside CatWalk should now show the city's name instead of the id number.

This should resolve ONLY the following traceback: AttributeError: <some_object> instance has no attribute '<some_column>ID' where some_object is your class name, and some_column is whatever you tried to joinColumn to.

comment:3 Changed 10 years ago by Kylotan

  • Version changed from 1.0.2 to 1.0.4b1

I get something very similar, except I've not used any joinColumns in my model (excluding the ones that were auto-generated via Identity).

...some lines removed...

  File "e:\code\python24\lib\site-packages\TurboGears-1.0.4b2-py2.4.egg\turbogea
rs\toolbox\catwalk\browse.py", line 197, in join_foreign_key
    return getattr(column.otherClass.q,foreign_key)
  File "E:\code\Python24\lib\site-packages\sqlobject-0.7.2-py2.4.egg\sqlobject\s
qlbuilder.py", line 374, in __getattr__
    raise AttributeError("%s instance has no attribute '%s'" % (self.soClass.__n
ame__, attr))
AttributeError: Task instance has no attribute 'taskID'

This is when clicking the 'browse' option for my TaskType? object.

The relationship between the two objects in question looks like this:

class TaskType(SQLObject):
    # some other fields removed
    instances = MultipleJoin('Task') # all existing tasks of this type

class Task(SQLObject):
    # some other fields removed
    tasktype = ForeignKey('TaskType', notNone=True, cascade=True)

I've changed the version on this to 1.0.4beta1, although I'm now running beta2 (not an option on the dropdown here yet).

comment:4 Changed 10 years ago by Kylotan

In my case, I wonder if it's some sort of bug relating to the renaming of tables and columns as a result of the CamelCase naming? I get a similar problem where my GridSquare? object has a ForeignKey?('TerrainType?') and the join wrongly looks for a TerrainID within it instead of TerrainTypeId? (terraintype_id in the db).

comment:5 Changed 9 years ago by faide

  • Severity changed from major to normal
  • Milestone changed from 1.1 to 1.1.1

comment:6 Changed 9 years ago by faide

  • Milestone changed from 1.6 to 1.5

comment:7 Changed 8 years ago by Chris Arndt

  • Owner changed from anonymous to Chris Arndt
  • Keywords needs patch, added
  • Milestone changed from 1.5 to 1.0.x bugfix

I can confirm that this is still an issue with TG 1.1rc1 and TG 1.0 svn r6685.

comment:8 Changed 8 years ago by Chris Arndt

  • Owner changed from Chris Arndt to chrisz

comment:9 Changed 8 years ago by chrisz

  • Status changed from new to closed
  • Resolution set to fixed

This is actually not a bug in Catwalk, but the result of a naming error in these models coupled with a deficiency of SQLObject that does not raise this naming error earlier: If you have a MultipleJoin like above, and you do not specify a joinColumn argument, then the join column is assumed to be called after the table with the MultipleJoin.

The naming error in the attached "modelbug" was that the foreign key was named "user", while the table name was actually "tg_user". The naming error in comment 3 was that the foreign key was called "tasktype" while the table name was "task_type".

Everything works as expected if you rename the foreign key to match the table name, or if you add a joinColumn argument to the MultipleJoin call specifying the different key name.

So nothing really needed to be fixed in Catwalk; but I have added a better error message for such naming problems in r6808.

Note: See TracTickets for help on using tickets.