[Sqlalchemy-tickets] [sqlalchemy] #2761: allow non-property objects to work with declarative string
Brought to you by:
zzzeek
|
From: sqlalchemy <mi...@zz...> - 2013-06-19 20:46:42
|
#2761: allow non-property objects to work with declarative string resolution
-------------------------+---------------------------------------
Reporter: zzzeek | Owner: zzzeek
Type: enhancement | Status: new
Priority: high | Milestone: 0.8.xx
Component: orm | Severity: minor - half an hour
Keywords: | Progress State: needs tests
-------------------------+---------------------------------------
{{{
#!python
from sqlalchemy import Column, Integer, String, ForeignKey, case
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.ext.hybrid import hybrid_property
from sqlalchemy.orm import relationship
Base = declarative_base()
class User(Base):
__tablename__ = 'user'
id = Column(Integer, primary_key=True)
firstname = Column(String(50))
lastname = Column(String(50))
game_id = Column(Integer, ForeignKey('game.id'))
@hybrid_property
def fullname(self):
if self.firstname is not None:
return self.firstname + " " + self.lastname
else:
return self.lastname
@fullname.expression
def fullname(cls):
return case([
(cls.firstname != None, cls.firstname + " " + cls.lastname),
], else_=cls.lastname)
class Game(Base):
__tablename__ = 'game'
id = Column(Integer, primary_key=True)
name = Column(String(50))
users = relationship("User", order_by="User.fullname")
if __name__ == '__main__':
game = Game(name="tetris")
}}}
patch:
{{{
#!diff
diff --git a/lib/sqlalchemy/ext/declarative/clsregistry.py
b/lib/sqlalchemy/ext/declarative/clsregistry.py
index 95aba93..a669e37 100644
--- a/lib/sqlalchemy/ext/declarative/clsregistry.py
+++ b/lib/sqlalchemy/ext/declarative/clsregistry.py
@@ -12,7 +12,7 @@ This system allows specification of classes and
expressions used in
from ...orm.properties import ColumnProperty, RelationshipProperty, \
SynonymProperty
from ...schema import _get_table_key
-from ...orm import class_mapper
+from ...orm import class_mapper, interfaces
from ... import util
from ... import exc
import weakref
@@ -190,19 +190,21 @@ class _GetColumns(object):
def __getattr__(self, key):
mp = class_mapper(self.cls, configure=False)
if mp:
- if not mp.has_property(key):
+ if key not in mp.all_orm_descriptors:
raise exc.InvalidRequestError(
"Class %r does not have a mapped column named
%r"
% (self.cls, key))
- prop = mp.get_property(key)
- if isinstance(prop, SynonymProperty):
- key = prop.name
- elif not isinstance(prop, ColumnProperty):
- raise exc.InvalidRequestError(
- "Property %r is not an instance of"
- " ColumnProperty (i.e. does not correspond"
- " directly to a Column)." % key)
+ desc = mp.all_orm_descriptors[key]
+ if desc.extension_type is interfaces.NOT_EXTENSION:
+ prop = desc.property
+ if isinstance(prop, SynonymProperty):
+ key = prop.name
+ elif not isinstance(prop, ColumnProperty):
+ raise exc.InvalidRequestError(
+ "Property %r is not an instance of"
+ " ColumnProperty (i.e. does not
correspond"
+ " directly to a Column)." % key)
return getattr(self.cls, key)
}}}
--
Ticket URL: <http://www.sqlalchemy.org/trac/ticket/2761>
sqlalchemy <http://www.sqlalchemy.org/>
The Database Toolkit for Python
|