[Sqlalchemy-tickets] [sqlalchemy] #2810: Single Item support for Association Proxy
Brought to you by:
zzzeek
|
From: sqlalchemy <mi...@zz...> - 2013-08-26 15:20:33
|
#2810: Single Item support for Association Proxy
-------------------------+-----------------------------------------
Reporter: jonathan | Owner: zzzeek
Type: defect | Status: new
Priority: medium | Milestone:
Component: cextensions | Severity: no triage selected yet
Keywords: | Progress State: awaiting triage
-------------------------+-----------------------------------------
Originally posted in the mailing list (
https://groups.google.com/forum/#!topic/sqlalchemy/Yehg9PIMQ_E )
Related to existing ticket "Scalar Support for Association Proxy"
http://www.sqlalchemy.org/trac/ticket/2751
An AttributeError is raised when an association proxy exists for an
relationship where `uselist=False`, there is no intermediary object, and
the objects association proxy is accessed.
This behavior makes it impossible to even check for an association proxy.
The expected behavior would be to return None, signifying there is no
currently proxied attribute.
given this example:
{{{
class Person:
# orm relationships are preceded by (o)ne or (l)ist
o_Person2Address_ActiveShipping = sa.orm.relationship(
"Person2Address",
primaryjoin="""and_( Person2Address.person_id==Person.id ,
Person2Address.role_id=='active-shipping' )""",
uselist=False )
active_shipping_address =
association_proxy('o_Person2Address_ActiveShipping', 'address')
class Person2Address:
address = sa.orm.relationship("Address",
primaryjoin="Person2Address.address_id==Address.id")
class Address:
pass
}}}
this works perfect when i have a Person2Address and address . I'd imagine
it works fine if the proxy is for an empty list too.
the problem is when o_Person2Address_ActiveShipping is an empty item (from
the uselist=False argument).
{{{
jim = dbSession.query( Person )
active_shipping = jim.o_Person2Address_ActiveShipping
type(active_shipping)
>> None
# this will raise an error
if jim.active_shipping_address :
# this will raise an error too
if jim.active_shipping_address and
jim.active_shipping_address.address :
print jim.active_shipping_address
}}}
that raises an error on the .active_shipping_address
{{{
File "/Users/jvanasco/webserver/environments/project-2.7.5/lib/python2.7
/site-packages/sqlalchemy/ext/associationproxy.py", line 241, in __get__
return self._scalar_get(getattr(obj, self.target_collection))
AttributeError: 'NoneType' object has no attribute 'media_asset'
}}}
i think a simple fix could be something like this ( line 240,
sqlalchemy/ext/associationproxy.py )
{{{
if self.scalar:
- if not getattr(obj, self.target_collection)
- return self._scalar_get(getattr(obj, self.target_collection))
else:
if self.scalar:
+ proxied = getattr(obj, self.target_collection)
+ if not proxied :
+ return None
+ return self._scalar_get(proxied)
else:
}}}
On the list, another person has reported encountering this and
monkeypatching with the same fix since 0.5.x
--
Ticket URL: <http://www.sqlalchemy.org/trac/ticket/2810>
sqlalchemy <http://www.sqlalchemy.org/>
The Database Toolkit for Python
|