[sqlalchemy] Re: Many to many self referential relationship.

2008-02-21 Thread Martin Pengelly-Phillips


Hi Michael,

As expected the trunk works perfectly.
I am also looking into the comparator example you pointed to as this
looks like it will help with a couple of other implementation details
as well.

Thanks again,


Martin

On Feb 20, 10:25 pm, Martin Pengelly-Phillips
[EMAIL PROTECTED] wrote:
 Thank you Michael - it's always good to get some validation when
 pushing your own knowledge of a system.
 I'll check out the trunk tomorrow, give it a whirl and report any
 findings then.

 Thanks again for the quick response,

 Martin

 On Feb 20, 6:31 pm, Michael Bayer [EMAIL PROTECTED] wrote:

  On Feb 20, 2008, at 1:01 PM, Martin Pengelly-Phillips wrote:

   I have attempted to solve this by using the concept of
   'forwardAssociations' with a backref of 'backwardAssociations' and
   then a custom property 'associations' that retrieves and sets the real
   attributes accordingly (let me know if you would like to see this code
   as well). However, even with this set up I find it hard to figure out
   how to then perform a query such as:

   # Get all entities that are in some way associated with entity 2
   (without using entity2.associations property)
   session.query(Entity).filter(or_(
  Entity.forwardAssociations.any(Entity.id==2),
  Entity.backwardAssociations.any(Entity.id==2)
   )).all()

   The query this generates though uses the same id for both sides of the
   association table which cannot therefore result in a match:
   entities.id = entitiesEntities.entity1_id AND
   entitiesEntities.entity2_id = entities.id AND entities.id = ?

  well i think everything you're doing is on the right track.  The any()
  operator and its friends have just been repaired in the latest trunk
  to recognize a self-referential relation and apply the appropriate
  aliasing to half of the join condition.  I haven't tested it with a
  many-to-many self referential yet but I think it should work.  give it
  a try and let me know what you get; I can add some m2m tests for it
  and ensure that its working if its not already.

  we also are working on getting better support for user-defined custom
  properties going such that they can be seamlessly used within Queries,
  so that you could also construct your query using your associations
  property, if you can define how comparison operations should be done.
  There is a way to do this right now using a slight bit of non-public
  API, where you can see an example of such 
  inhttp://www.sqlalchemy.org/trac/browser/sqlalchemy/trunk/examples/vert...
; the comparable_property allows the injection of a Comparator
  object from where you can define things like __eq__(), any(), etc.
--~--~-~--~~~---~--~~
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] Behavior question with association proxy with custom collection class

2008-02-21 Thread Ronald Lew

I was exploring the association proxy example in the documentation and
then explored the use of a mapped collection as the custom collection
class with mixed results.  When attempting to append, an
AttributeError _AssociationDict object has no attribute append
occurred.  Then, I tried subclassing MappedCollection, created my own
append method and have SQLAlchemy instrument it but the results were
the same.  Here's the code I was testing it with:

from sqlalchemy import Boolean, Column, ForeignKey, Integer, String,
Table
from sqlalchemy.orm import relation
from sqlalchemy.orm.collections import mapped_collection,
MappedCollection, collection
from sqlalchemy.ext.associationproxy import association_proxy
from turbogears.database import metadata, session

users_table = Table('users', metadata,
Column('id', Integer, primary_key=True),
Column('name', String(64))
)

keywords_table = Table('keywords', metadata,
Column('id', Integer, primary_key=True),
Column('keyword', String(64))
)

userkeywords_table = Table('userkeywords', metadata,
Column('user_id', Integer, ForeignKey(users.id),
primary_key=True),
Column('keyword_id', Integer, ForeignKey(keywords.id),
primary_key=True)
)

def _create_uk(keyword):
return UserKeyword(keyword=keyword)

class User(object):
def __init__(self, id, name):
self.id = id
self.name = name
keywords = association_proxy('user_keywords', 'keyword',
creator=_create_uk)

class Keyword(object):
def __init__(self, id, keyword):
self.id = id
self.keyword = keyword
def __repr__(self):
return 'Keyword(%s)' % repr(self.keyword)

class UserKeyword(object):
def __init__(self, user=None, keyword=None):
self.user = user
self.keyword = keyword

session.mapper(Keyword, keywords_table)
session.mapper(User, users_table, properties={
'user_keywords':relation(UserKeyword)
})
session.mapper(UserKeyword, userkeywords_table, properties={
'user':relation(User),
'keyword':relation(Keyword)
})

user = User('1', 'number')
kw1 = Keyword('0', 'zero')
user.user_keywords.append(UserKeyword(user, kw1))

for kw in (Keyword('1', 'one'), Keyword('2', 'two'), Keyword('3',
'three')):
user.keywords.append(kw)


Portion of code changed with mapped collection (which won't work):
session.mapper(User, users_table, properties={
#'user_keywords':relation(UserKeyword)
'user_keywords':relation(UserKeyword,
collection_class=mapped_collection(lambda item: item.keyword.id))
})


Code for customized collection (also won't work):
class MyCollection(MappedCollection):
def __init__(self, keyfunc=lambda item: item.id):
MappedCollection.__init__(self, keyfunc=keyfunc)

@collection.appender
def append(self, item):
MappedCollection.set(self, item)

@collection.remover
def remove(self, item):
MappedCollection.remove(self, item)

u_collection = lambda: MyCollection(keyfunc=lambda item:
item.keyword.id)
session.mapper(User, users_table, properties={
#'user_keywords':relation(UserKeyword)
'user_keywords':relation(UserKeyword,
collection_class=u_collection)
})
--~--~-~--~~~---~--~~
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: Behavior question with association proxy with custom collection class

2008-02-21 Thread Ronald Lew

I assume a getset_factory is needed for the association proxy.  Any
examples?

On Feb 21, 8:38 am, Ronald Lew [EMAIL PROTECTED] wrote:
 I was exploring the association proxy example in the documentation and
 then explored the use of a mapped collection as the custom collection
 class with mixed results.  When attempting to append, an
 AttributeError _AssociationDict object has no attribute append
 occurred.  Then, I tried subclassing MappedCollection, created my own
 append method and have SQLAlchemy instrument it but the results were
 the same.  Here's the code I was testing it with:

 from sqlalchemy import Boolean, Column, ForeignKey, Integer, String,
 Table
 from sqlalchemy.orm import relation
 from sqlalchemy.orm.collections import mapped_collection,
 MappedCollection, collection
 from sqlalchemy.ext.associationproxy import association_proxy
 from turbogears.database import metadata, session

 users_table = Table('users', metadata,
 Column('id', Integer, primary_key=True),
 Column('name', String(64))
 )

 keywords_table = Table('keywords', metadata,
 Column('id', Integer, primary_key=True),
 Column('keyword', String(64))
 )

 userkeywords_table = Table('userkeywords', metadata,
 Column('user_id', Integer, ForeignKey(users.id),
 primary_key=True),
 Column('keyword_id', Integer, ForeignKey(keywords.id),
 primary_key=True)
 )

 def _create_uk(keyword):
 return UserKeyword(keyword=keyword)

 class User(object):
 def __init__(self, id, name):
 self.id = id
 self.name = name
 keywords = association_proxy('user_keywords', 'keyword',
 creator=_create_uk)

 class Keyword(object):
 def __init__(self, id, keyword):
 self.id = id
 self.keyword = keyword
 def __repr__(self):
 return 'Keyword(%s)' % repr(self.keyword)

 class UserKeyword(object):
 def __init__(self, user=None, keyword=None):
 self.user = user
 self.keyword = keyword

 session.mapper(Keyword, keywords_table)
 session.mapper(User, users_table, properties={
 'user_keywords':relation(UserKeyword)})

 session.mapper(UserKeyword, userkeywords_table, properties={
 'user':relation(User),
 'keyword':relation(Keyword)

 })

 user = User('1', 'number')
 kw1 = Keyword('0', 'zero')
 user.user_keywords.append(UserKeyword(user, kw1))

 for kw in (Keyword('1', 'one'), Keyword('2', 'two'), Keyword('3',
 'three')):
 user.keywords.append(kw)

 Portion of code changed with mapped collection (which won't work):
 session.mapper(User, users_table, properties={
 #'user_keywords':relation(UserKeyword)
 'user_keywords':relation(UserKeyword,
 collection_class=mapped_collection(lambda item: item.keyword.id))

 })

 Code for customized collection (also won't work):
 class MyCollection(MappedCollection):
 def __init__(self, keyfunc=lambda item: item.id):
 MappedCollection.__init__(self, keyfunc=keyfunc)

 @collection.appender
 def append(self, item):
 MappedCollection.set(self, item)

 @collection.remover
 def remove(self, item):
 MappedCollection.remove(self, item)

 u_collection = lambda: MyCollection(keyfunc=lambda item:
 item.keyword.id)
 session.mapper(User, users_table, properties={
 #'user_keywords':relation(UserKeyword)
 'user_keywords':relation(UserKeyword,
 collection_class=u_collection)

 })
--~--~-~--~~~---~--~~
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: Behavior question with association proxy with custom collection class

2008-02-21 Thread jason kirtland

Ronald Lew wrote:
 I wanted to use a mapped collection or a customized collection instead
 of the default list for the collection class and have the keyword's id
 as the key.  In addition, I wanted to keep using the append but that
 seems impossible now since I cannot fool association dict to use it.
 I wanted to not have to change the below code:
 
 for kw in (Keyword('1','one'), Keyword('2','two'),
 Keyword('3','three')):
 user.keywords.append(kw) # cannot use this any more

The association proxy accepts the proxy implementation type as an 
optional argument.  You can subclass the proxy dict type and add an 
append method.  See:

http://www.sqlalchemy.org/docs/04/sqlalchemy_ext_associationproxy.html#docstrings_sqlalchemy.ext.associationproxy_AssociationProxy

and:

http://www.sqlalchemy.org/trac/browser/sqlalchemy/trunk/lib/sqlalchemy/ext/associationproxy.py#L227



--~--~-~--~~~---~--~~
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: DPAPI Error

2008-02-21 Thread jon

Mike,

Sorry to get back to you on this so late. I installed 0.4.3 and things
seem to be humming along nicely. Should that be the case or should I
expect some madness from my app soon?

Thanks a million!

Jon

On Jan 30, 1:09 pm, Michael Bayer [EMAIL PROTECTED] wrote:
 hey jon -

 OK, I found an issue that is very likely to be what you are
 experiencing;  easy to fix as always but unless you can run on SVN
 trunk r4106, you'll have to workaround it.

 There may be a schema identifier somewhere in your app that contains
 the identifier 'roleseq' as a unicode string, which is getting cached
 as a u''.

 So if you can't hunt that down (which you shouldn't have to), you can
 force it to cache the non-unicode string for now if you do this to
 your engine as early as possible (i.e. before the incorrect value gets
 cached):

 
 engine.dialect.identifier_preparer.format_sequence(Sequence('roleseq'))

 hope thats the issue.

 - mike

 On Jan 30, 2008, at 3:14 PM, jon wrote:



  Hi Mike,

  Thanks for your patience...here is the entry I have for that table in
  model/__init__.py

  role_table = Table('role', metadata,
Column('roleseq', Integer, Sequence('roleseq'),
  primary_key=True),

  I know that I specifically didn't set things up for Unicode in this
  app either...this file is the only one that contains the Sequence
  declaration.

  Thanks,

  Jon

  On Jan 30, 11:34 am, Michael Bayer [EMAIL PROTECTED] wrote:
  On Jan 30, 2008, at 2:10 PM, jon wrote:

  Thanks for getting back to me and apologies for the stacktrace
  barf ;-)

  One thing...I have the following line in my environment.py:

  config['pylons.g'].sa_engine = engine_from_config(config,
  'sqlalchemy.', convert_unicode=True, pool_size=1, max_overflow=3)

  I can turn on/off the convert_unicode option and I still get the
  same
  error. I spoke with one of our DBAs and he said the results of
  roleseq.nextval is a number. SA is looking for a String here or
  None,
  according to the exception error:

  exceptions.TypeError: expecting None or a string

  Sooo...is this still an SA thing and if so what do you suggest as a
  workaround?

  jon -

  none of that has anything to do with the error message here.  You
  need
  to grep thorugh your code for the specific string :
  Sequence(u'roleseq'), or something equivalent.  I know its there
  because the Oracle dialect does not invent or reflect any sequence
  names.  You need to make that sequence name into a regular string
  object; as above you'd take out the u inside the parenthesis.

  let me know when you find it as I'd like to confirm this is the
  source
  of the issuethanks !

  - mike
--~--~-~--~~~---~--~~
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
-~--~~~~--~~--~--~---