Bugs item #1642143, was opened at 2007-01-23 07:07
Message generated for change (Comment added) made by phd
You can respond by visiting:
https://sourceforge.net/tracker/?func=detail&atid=540672&aid=1642143&group_id=74338
Please note that this message will contain a full copy of the comment thread,
including the initial issue submission, for this request,
not just the latest update.
Category: General
Group: SQLObject from repository
>Status: Closed
>Resolution: Invalid
Priority: 5
Private: No
Submitted By: Leandro Lucarella (llucax)
Assigned to: Oleg Broytmann (phd)
Summary: [PATCH] TypeError:unhashable instance using sqlbuilder.Table
Initial Comment:
Hi! Maybe this is a pretty weird use case (please let me know if there is a better way to do this).
What I wanted was just to store an ordered list of many-to-many relationships. To achieve this, I used an special intermediate table with an extra field for ordering. Then I write some custom SQL queries to do the join using sqlbuilder.table (Table instance) and friends.
The problem is I'm getting a TypeError ("TypeError: unhashable instance") when doing that, because Table and Field don't have the __hash__ magic method (and for the records, none SQLExpression does either).
Well, long story short, this is fixed by just adding the __hash__ method to SQLExpression class. Here is the patch and a simple testcase.
Again, please tell me if there is a cleaner way to achieve this with SQLObject.
Thanks!
----------------------------------------------------------------------
>Comment By: Oleg Broytmann (phd)
Date: 2007-01-23 20:59
Message:
Logged In: YES
user_id=4799
Originator: NO
No need to make SQLExpresshion hashable. You problem must be fixed this
way:
clauseTables=("task_plan", Plan.sqlmeta.table),
clauseTables must be a sequence of tables names (strings), not objects.
----------------------------------------------------------------------
Comment By: Leandro Lucarella (llucax)
Date: 2007-01-23 15:29
Message:
Logged In: YES
user_id=240225
Originator: YES
I know I can create the intermediate table using SQLObject, but I don't
want to, because this generates an extra 'id' field in the table that is
useless. What I really wanted to do was add an "OrderedRelatedJoin" or
something like that but I got lost because RelatedJoin is so tied up with
dbconnection module. I expected to be just plan (sqlbuilder) SQL in the
join module.
Another simple solution (but I think not too easy to implement because
AFAIK SQLObject is to tied up too to the single primary key) is to let a
SQLObject to have a composed primary key and use the two FK as the PK.
Anyways, I'm not using the Table object as dict, SQLObject is =)
If you run the testcase, you'll get:
Traceback (most recent call last):
File "testcase.py", line 70, in ?
plan.tasks = (Task(name="task1"), Task(name="task2"),
Task(name="task3"))
File "testcase.py", line 48, in _set_tasks
old = frozenset([t.id for t in self.tasks])
File "testcase.py", line 38, in _get_tasks
orderBy=task_plan_table.pos,
File "/tmp/0.8/sqlobject/main.py", line 1347, in select
join=join, forUpdate=forUpdate)
File "/tmp/0.8/sqlobject/sresults.py", line 20, in __init__
tablesDict[table] = 1
TypeError: unhashable instance
I know I could use plain old strings instead of the Table object instance,
but I found the later more pythonic (I feel like I'm not messing arround
with raw SQL =D).
And BTW, it's a very simple patch (3 lines of code, it's 'def
__has__(self): return hash(str(self))' inside SQLExpression class
declaration. It couldn't hurt anybody. And as plus it completes a little
more the SQLExpression in general so you can use SQLExpressions as dict
keys in general.
PS. Sorry about the patch, I've posted some others in the past here and
nobody complained, maybe there was a change in the policy, that was
about... 2 years ago. Damn! The time pass by... ;-P
----------------------------------------------------------------------
Comment By: Oleg Broytmann (phd)
Date: 2007-01-23 12:46
Message:
Logged In: YES
user_id=4799
Originator: NO
First, you don't need to create the intermediate table yourself. The
development FAQ shows how to do this in SQLObject:
http://sqlobject.org/devel/FAQ.html#how-can-i-define-my-own-intermediate-table-in-my-many-to-many-relationship
Second, I do not understand where from came the TypeError. Are you trying
to use Tables as a dict keys?
PS. Patches should be put in patches, really. ;)
----------------------------------------------------------------------
Comment By: Leandro Lucarella (llucax)
Date: 2007-01-23 07:11
Message:
Logged In: YES
user_id=240225
Originator: YES
The patch apply cleanly to the 0.8 branch too. I hope it make it to 0.8 =)
----------------------------------------------------------------------
Comment By: Leandro Lucarella (llucax)
Date: 2007-01-23 07:09
Message:
Logged In: YES
user_id=240225
Originator: YES
File Added: sqlexpression.hash.patch
----------------------------------------------------------------------
You can respond by visiting:
https://sourceforge.net/tracker/?func=detail&atid=540672&aid=1642143&group_id=74338
|