[sqlalchemy] Re: Python 2.6 hash behavior change

2008-03-04 Thread Denis S. Otkidach

On Mon, Mar 3, 2008 at 8:23 PM, Michael Bayer [EMAIL PROTECTED] wrote:
  We define __eq__() all over the place so that would be a lot of
  __hash__() methods to add, all of which return id(self).  I wonder if
  we shouldn't just make a util.Mixin called Hashable so that we can
  centralize the idea.

Are you sure this is a correct way? Below is an example demonstrating
the problem with it:

 class C(object):
... def __init__(self, value):
... self._value = value
... def __eq__(self, other):
... return self._value==other._value
... def __hash__(self):
... return id(self)
...
 c1 = C(1)
 c2 = C(1)
 c1==c2
True
 d = {c1: None}
 c1 in d
True
 c2 in d
False

I.e. although c2 is equal to c1 and thus should be found in
dictionary, it is not. The defined __hash__ method must return equal
numbers for equal object.

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalchemy@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~--~~~~--~~--~--~---



[sqlalchemy] Re: AuditLog my first attempt

2008-03-04 Thread svilen

On Tuesday 04 March 2008 12:34:11 Marco De Felice wrote:
 So after some coding and thanks to sdobrev previous reply I came up
 with the following mapperextension that allows for a client side
 update log to a different table (logtable name = table_prefix +
 original table name) with a logoperation field added.

 Any comment is welcome as I don't really know SA internals, it
 seems to work against a simple mapped table.
for multitable mappers... 
 a) log as mapper-access and not table-access
 b) or, while walking mapper.columns, each column knows which table it 
comes from, so for those changed u can log them separately

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalchemy@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~--~~~~--~~--~--~---



[sqlalchemy] Re: Python 2.6 hash behavior change

2008-03-04 Thread Michael Bayer


On Mar 4, 2008, at 4:26 AM, Denis S. Otkidach wrote:


 On Mon, Mar 3, 2008 at 8:23 PM, Michael Bayer [EMAIL PROTECTED] 
  wrote:
 We define __eq__() all over the place so that would be a lot of
 __hash__() methods to add, all of which return id(self).  I wonder if
 we shouldn't just make a util.Mixin called Hashable so that we can
 centralize the idea.

 Are you sure this is a correct way? Below is an example demonstrating
 the problem with it:

 class C(object):
 ... def __init__(self, value):
 ... self._value = value
 ... def __eq__(self, other):
 ... return self._value==other._value
 ... def __hash__(self):
 ... return id(self)
 ...
 c1 = C(1)
 c2 = C(1)
 c1==c2
 True
 d = {c1: None}
 c1 in d
 True
 c2 in d
 False

 I.e. although c2 is equal to c1 and thus should be found in
 dictionary, it is not. The defined __hash__ method must return equal
 numbers for equal object.


Well actually, in our particular case that's the behavior that we *do*  
want; pretty much everywhere we've defined __eq__(), we've done it not  
to redefine what it means for a==b, but to produce SQL expressions -  
so in that sense __eq__() is entirely broken for its normal usage in  
SQLAlchemy (as well as in all the other SQL tools out there using this  
approach).  For this reason, internally we can't do things like d in  
[a,b,c] if those are SQL expressions, since __eq__() evaluates to  
true in all cases - we use sets when we need a collection of SQL  
expressions where we can test for presence, so that their hash value  
is used.

However, while Im not familiar with the internals of Python  
dictionaries, depending on how they implemented it we still may need  
to use IdentitySet and IdentityDict, two classes (well we have the  
first one at least) which ignore the __hash__() and __eq__() methods  
entirely and hash their contents strictly based on id(obj).   This is  
because a hashtable usually stores items in buckets based on a  
modulus of the __hash__() value; if two items are in the same bucket,  
an equality comparison is used to locate the correct object.  If  
Python's dict uses __eq__() for the equality comparison, we'd be in  
trouble.  I have a strong suspicion that they do not (since I think we  
would have noticed by now), and that they use __hash__() for the  
equality comparison as well, but I'm not sure; and also not sure if  
this is slated to change in py2.6.

I think I might want to look into defining in util  ExpressionSet /  
ExpressionKeyDict set symbols (subject to the new names jek is sure to  
propose... ;)  ) which would be used throughout the source code to  
store SQL expression constructs as keys.  That way at least we can  
change the underlying implementation based on observed quirks of the  
version in use.


--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalchemy@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~--~~~~--~~--~--~---



[sqlalchemy] having problem with non_primary mapper in 0.4.3

2008-03-04 Thread Jonathan Vanasco

this is self explanatory, but error is below

i'm using sqlalchemy to reflect a table. it reads it fine.
when i try to assign a mapper, i get has no attribute '_class_state'

looking at orm.mapper.py

734:
if self.non_primary:
self._class_state = self.class_._class_state
_mapper_registry[self] = True
return


if i look at the dict around 735, self.class_._class_state not set

i couldn't find where self.class_._class_state was set elsewhere in
the code

is this a bug?  could something else be at fault?

==

  File /Library/Frameworks/Python.framework/Versions/2.5/lib/
python2.5/site-packages/SQLAlchemy-0.4.3-py2.5.egg/sqlalchemy/orm/
__init__.py, line 548, in mapper
return Mapper(class_, local_table, *args, **params)
  File /Library/Frameworks/Python.framework/Versions/2.5/lib/
python2.5/site-packages/SQLAlchemy-0.4.3-py2.5.egg/sqlalchemy/orm/
mapper.py, line 158, in __init__
self._compile_class()
  File /Library/Frameworks/Python.framework/Versions/2.5/lib/
python2.5/site-packages/SQLAlchemy-0.4.3-py2.5.egg/sqlalchemy/orm/
mapper.py, line 737, in _compile_class
self._class_state = self.class_._class_state
AttributeError: type object '_attachment_type' has no attribute
'_class_state'

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalchemy@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~--~~~~--~~--~--~---



[sqlalchemy] Re: Integrating the ORM with Trellis

2008-03-04 Thread Phillip J. Eby

At 02:04 PM 3/3/2008 -0500, Michael Bayer wrote:

the bug is that unregister_attribute() is not working, which the test
suite is using to remove and re-register new instrumentation:

 class Foo(object):
 pass

  attributes.register_attribute(Foo, collection,
uselist=True, typecallable=set, useobject=True)
  assert
attributes.get_class_state(Foo).is_instrumented(collection)
  attributes.unregister_attribute(Foo, collection)
  assert not
attributes.get_class_state(Foo).is_instrumented(collection)

seems like unregister_attribute() is still doing the old thing of just
del class.attr, so we'd just need to stick a hook similar to
instrument_attribute for this on ClassState which will take over the
job.

looks good !

Okay, so I did a matching uninstrument_attribute and 
pre_uninstrument_attribute, which look like really dumb names at this 
point.  I propose the following name changes (in addition to the ones 
in my previous patch):

pre_instrument_attribute - install_descriptor
pre_uninstrument_attribute - uninstall_descriptor

That okay?  instrument_attribute will then call install_descriptor to 
do the actual installing.  And of course the hooks on the adapted 
thingy from the class would work the same way.

If that's okay with you, then after I'm done I'll post a patch for 
review before checkin.  After that, I'll start work on the 
Trellis-side support for this, and then eventually dig into  collections stuff.


--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalchemy@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~--~~~~--~~--~--~---



[sqlalchemy] Mapping and querying multiple levels of foreign key'd tables

2008-03-04 Thread Christoph Haas

Dear list...

Actually I'm trying something rather simple so I'm surprised myself that
it got me stuck. Bear with me that I'm not providing much code but the
application is not written in english so the database models aren't
either.

Basically I have three tables like 'companies', 'departments' and
'employees'. I have already set up foreign keys and gave all of them
one-to-many relationships. So a company has several departments. And
each department has several employees. So for an ORM-mapped company
object mycompany I can get the departments by the property
mycompany.departments. Works well.

Now I'd like to create a query for all employees of a certain company. 
And I'm not sure how to properly define a mapper relation propery that
would give me that. Like mycompany.employees. Do I have to use JOINs
myself in the mapper?

In my application I'd then like to query like this:
Session.query(Employee).filter_by(employee.company=my_company)

Thanks for any hints.

 Christoph
-- 
[EMAIL PROTECTED]  www.workaround.org   JID: [EMAIL PROTECTED]
gpg key: 79CC6586 fingerprint: 9B26F48E6F2B0A3F7E33E6B7095E77C579CC6586

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalchemy@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~--~~~~--~~--~--~---