Changeset 342

Show
Ignore:
Timestamp:
06/18/08 18:37:18 (5 years ago)
Author:
ged
Message:

- remove deprecated methods on Entity
- pulled entity mapping and target resolving code from EntityMeta and

Relationship so that people can provide their own registry with any behavior
they like.

Location:
elixir/trunk/elixir
Files:
3 modified

Legend:

Unmodified
Added
Removed
  • elixir/trunk/elixir/__init__.py

    r334 r342  
    2121    from sets import Set as set 
    2222 
     23import sys 
    2324import warnings 
     25 
     26from py23compat import rsplit 
     27 
    2428import sqlalchemy 
    2529from sqlalchemy.types import * 
     
    9397# default entity collection 
    9498class AttributeEntityList(list): 
     99    _entities = {} 
    95100     
    96101    def __init__(self): 
     
    101106        if key in self._entity_map: 
    102107            warnings.warn('An entity named `%s` is already registered!' % key) 
     108 
     109        # build a dict of entities for each frame where there are entities 
     110        # defined. 3 is because map_entity is called by: 
     111        # EntityDescriptor::setup_options (which is called by) 
     112        # EntityMeta::__init__ 
     113        # which is called when the entity is defined 
     114        caller_frame = sys._getframe(3) 
     115        cid = entity._caller = id(caller_frame) 
     116        caller_entities = self._entities.setdefault(cid, {}) 
     117        caller_entities[key] = entity 
     118 
     119        # Append all entities which are currently visible by the entity. This  
     120        # will find more entities only if some of them where imported from  
     121        # another module. 
     122        for ent in [e for e in caller_frame.f_locals.values()  
     123                         if isinstance(e, EntityMeta)]: 
     124            caller_entities[ent.__name__] = ent 
     125         
    103126        self._entity_map[key] = entity 
    104127     
     128    def resolve(self, key, entity=None): 
     129        if isinstance(key, EntityMeta): 
     130            return key 
     131        else: 
     132            path = rsplit(key, '.', 1) 
     133            classname = path.pop() 
     134 
     135            if path: 
     136                # Do we have a fully qualified entity name? 
     137                module = sys.modules[path.pop()] 
     138                return getattr(module, classname, None) 
     139            else: 
     140                # If not, try the list of entities of the "caller" of the  
     141                # source class. Most of the time, this will be the module  
     142                # the class is defined in. But it could also be a method  
     143                # (inner classes). 
     144                caller_entities = self._entities[entity._caller] 
     145                return caller_entities[classname] 
     146 
    105147    def __getattr__(self, key):         
    106148        return self._entity_map.get(key) 
  • elixir/trunk/elixir/entity.py

    r338 r342  
    1010 
    1111import sqlalchemy 
    12 from sqlalchemy                    import Table, Column, Integer, \ 
    13                                           desc, ForeignKey, and_, \ 
    14                                           ForeignKeyConstraint 
    15 from sqlalchemy.orm                import Query, MapperExtension, \ 
    16                                           mapper, object_session, \ 
    17                                           EXT_CONTINUE, \ 
    18                                           polymorphic_union 
     12from sqlalchemy     import Table, Column, Integer, desc, ForeignKey, and_, \ 
     13                           ForeignKeyConstraint 
     14from sqlalchemy.orm import Query, MapperExtension, mapper, object_session, \ 
     15                           EXT_CONTINUE, polymorphic_union 
    1916try: 
    2017    from sqlalchemy.ext.sessioncontext import SessionContext 
     
    8683        self.builders = [] 
    8784 
    88         self.is_base = is_base(entity) 
    8985        self.parent = None 
    9086        self.children = [] 
    9187 
    9288        for base in entity.__bases__: 
    93             if isinstance(base, EntityMeta) and not is_base(base): 
     89            if isinstance(base, EntityMeta) and is_entity(base): 
    9490                if self.parent: 
    9591                    raise Exception('%s entity inherits from several entities,' 
     
    278274                    self.entity.table = self.parent.table  
    279275 
    280                     # re-add the entity columns to the parent entity so that they 
    281                     # are added to the parent's table (whether the parent's table 
    282                     # is already setup or not). 
     276                    # re-add the entity columns to the parent entity so that  
     277                    # they are added to the parent's table (whether the  
     278                    # parent's table is already setup or not). 
    283279                    for col in self.columns: 
    284280                        self.parent._descriptor.add_column(col) 
     
    655651        return getattr(owner, self.attrname) 
    656652 
    657 def is_base(cls): 
     653def is_entity(cls): 
    658654    """ 
    659     Scan bases classes to see if any is an instance of EntityMeta. If we 
    660     don't find any, it means the current entity is a base class (like  
    661     the 'Entity' class). 
     655    Scan the bases classes of `cls` to see if any is an instance of  
     656    EntityMeta. If we don't find any, it means it is either an unrelated class 
     657    or an entity base class (like the 'Entity' class). 
    662658    """ 
    663659    for base in cls.__bases__: 
    664660        if isinstance(base, EntityMeta): 
    665             return False 
    666     return True 
     661            return True 
     662    return False 
    667663 
    668664class EntityMeta(type): 
     
    672668    for your entities (ie you don't want to use the provided 'Entity' class). 
    673669    """ 
    674     _entities = {} 
    675670 
    676671    def __init__(cls, name, bases, dict_): 
     
    679674        # be registered in an entity collection, nor to have a table name and  
    680675        # so on.  
    681         if is_base(cls): 
     676        if not is_entity(cls): 
    682677            return 
    683  
    684         # build a dict of entities for each frame where there are entities 
    685         # defined 
    686         caller_frame = sys._getframe(1) 
    687         cid = cls._caller = id(caller_frame) 
    688         caller_entities = EntityMeta._entities.setdefault(cid, {}) 
    689         caller_entities[name] = cls 
    690  
    691         # Append all entities which are currently visible by the entity. This  
    692         # will find more entities only if some of them where imported from  
    693         # another module. 
    694         for entity in [e for e in caller_frame.f_locals.values()  
    695                          if isinstance(e, EntityMeta)]: 
    696             caller_entities[entity.__name__] = entity 
    697678 
    698679        # create the entity descriptor 
     
    772753    #TODO: we might want to add all columns that will be available as 
    773754    #attributes on the class itself (in SA 0.4). This would be a pretty 
    774     #rare usecase, as people will hit the query attribute before the 
     755    #rare usecase, as people will normally hit the query attribute before the 
    775756    #column attributes, but still... 
    776757    for name in ('c', 'table', 'mapper', 'query'): 
     
    1008989    get = classmethod(get) 
    1009990 
    1010     #-----------------# 
    1011     # DEPRECATED LAND # 
    1012     #-----------------# 
    1013  
    1014     def filter(cls, *args, **kwargs): 
    1015         warnings.warn("The filter method on the class is deprecated." 
    1016                       "You should use cls.query.filter(...)",  
    1017                       DeprecationWarning, stacklevel=2) 
    1018         return cls.query.filter(*args, **kwargs) 
    1019     filter = classmethod(filter) 
    1020  
    1021     def filter_by(cls, *args, **kwargs): 
    1022         warnings.warn("The filter_by method on the class is deprecated." 
    1023                       "You should use cls.query.filter_by(...)",  
    1024                       DeprecationWarning, stacklevel=2) 
    1025         return cls.query.filter_by(*args, **kwargs) 
    1026     filter_by = classmethod(filter_by) 
    1027  
    1028     def select(cls, *args, **kwargs): 
    1029         warnings.warn("The select method on the class is deprecated." 
    1030                       "You should use cls.query.filter(...).all()",  
    1031                       DeprecationWarning, stacklevel=2) 
    1032         return cls.query.filter(*args, **kwargs).all() 
    1033     select = classmethod(select) 
    1034  
    1035     def select_by(cls, *args, **kwargs): 
    1036         warnings.warn("The select_by method on the class is deprecated." 
    1037                       "You should use cls.query.filter_by(...).all()",  
    1038                       DeprecationWarning, stacklevel=2) 
    1039         return cls.query.filter_by(*args, **kwargs).all() 
    1040     select_by = classmethod(select_by) 
    1041  
    1042     def selectfirst(cls, *args, **kwargs): 
    1043         warnings.warn("The selectfirst method on the class is deprecated." 
    1044                       "You should use cls.query.filter(...).first()",  
    1045                       DeprecationWarning, stacklevel=2) 
    1046         return cls.query.filter(*args, **kwargs).first() 
    1047     selectfirst = classmethod(selectfirst) 
    1048  
    1049     def selectfirst_by(cls, *args, **kwargs): 
    1050         warnings.warn("The selectfirst_by method on the class is deprecated." 
    1051                       "You should use cls.query.filter_by(...).first()",  
    1052                       DeprecationWarning, stacklevel=2) 
    1053         return cls.query.filter_by(*args, **kwargs).first() 
    1054     selectfirst_by = classmethod(selectfirst_by) 
    1055  
    1056     def selectone(cls, *args, **kwargs): 
    1057         warnings.warn("The selectone method on the class is deprecated." 
    1058                       "You should use cls.query.filter(...).one()",  
    1059                       DeprecationWarning, stacklevel=2) 
    1060         return cls.query.filter(*args, **kwargs).one() 
    1061     selectone = classmethod(selectone) 
    1062  
    1063     def selectone_by(cls, *args, **kwargs): 
    1064         warnings.warn("The selectone_by method on the class is deprecated." 
    1065                       "You should use cls.query.filter_by(...).one()",  
    1066                       DeprecationWarning, stacklevel=2) 
    1067         return cls.query.filter_by(*args, **kwargs).one() 
    1068     selectone_by = classmethod(selectone_by) 
    1069  
    1070     def join_to(cls, *args, **kwargs): 
    1071         warnings.warn("The join_to method on the class is deprecated." 
    1072                       "You should use cls.query.join(...)",  
    1073                       DeprecationWarning, stacklevel=2) 
    1074         return cls.query.join_to(*args, **kwargs).all() 
    1075     join_to = classmethod(join_to) 
    1076  
    1077     def join_via(cls, *args, **kwargs): 
    1078         warnings.warn("The join_via method on the class is deprecated." 
    1079                       "You should use cls.query.join(...)",  
    1080                       DeprecationWarning, stacklevel=2) 
    1081         return cls.query.join_via(*args, **kwargs).all() 
    1082     join_via = classmethod(join_via) 
    1083  
    1084     def count(cls, *args, **kwargs): 
    1085         warnings.warn("The count method on the class is deprecated." 
    1086                       "You should use cls.query.filter(...).count()",  
    1087                       DeprecationWarning, stacklevel=2) 
    1088         return cls.query.filter(*args, **kwargs).count() 
    1089     count = classmethod(count) 
    1090  
    1091     def count_by(cls, *args, **kwargs): 
    1092         warnings.warn("The count_by method on the class is deprecated." 
    1093                       "You should use cls.query.filter_by(...).count()",  
    1094                       DeprecationWarning, stacklevel=2) 
    1095         return cls.query.filter_by(*args, **kwargs).count() 
    1096     count_by = classmethod(count_by) 
    1097  
    1098     def options(cls, *args, **kwargs): 
    1099         warnings.warn("The options method on the class is deprecated." 
    1100                       "You should use cls.query.options(...)",  
    1101                       DeprecationWarning, stacklevel=2) 
    1102         return cls.query.options(*args, **kwargs) 
    1103     options = classmethod(options) 
    1104  
    1105     def instances(cls, *args, **kwargs): 
    1106         warnings.warn("The instances method on the class is deprecated." 
    1107                       "You should use cls.query.instances(...)",  
    1108                       DeprecationWarning, stacklevel=2) 
    1109         return cls.query.instances(*args, **kwargs) 
    1110     instances = classmethod(instances) 
    1111  
    1112  
    1113  
  • elixir/trunk/elixir/relationships.py

    r328 r342  
    327327''' 
    328328 
     329import sys 
     330 
    329331from sqlalchemy         import ForeignKeyConstraint, Column, \ 
    330332                               Table, and_ 
    331333from sqlalchemy.orm     import relation, backref 
     334from sqlalchemy.ext.associationproxy import association_proxy 
     335 
     336import options 
    332337from elixir.statements  import ClassMutator 
    333338from elixir.fields      import Field 
    334339from elixir.properties  import Property 
    335340from elixir.entity      import EntityDescriptor, EntityMeta 
    336 from sqlalchemy.ext.associationproxy import association_proxy 
    337  
    338 from py23compat import rsplit 
    339  
    340 import sys 
    341 import options 
     341 
    342342 
    343343__doc_all__ = [] 
     
    415415        self.property = relation(self.target, **kwargs) 
    416416        self.entity._descriptor.add_property(self.name, self.property) 
    417      
     417 
    418418    def target(self): 
    419419        if not self._target: 
    420             if isinstance(self.of_kind, EntityMeta): 
    421                 self._target = self.of_kind 
    422             else: 
    423                 path = rsplit(self.of_kind, '.', 1) 
    424                 classname = path.pop() 
    425  
    426                 if path: 
    427                     # do we have a fully qualified entity name? 
    428                     module = sys.modules[path.pop()] 
    429                     self._target = getattr(module, classname, None) 
    430                 else: 
    431                     # If not, try the list of entities of the "caller" of the  
    432                     # source class. Most of the time, this will be the module  
    433                     # the class is defined in. But it could also be a method  
    434                     # (inner classes). 
    435                     caller_entities = EntityMeta._entities[self.entity._caller] 
    436                     self._target = caller_entities[classname] 
     420            collection = self.entity._descriptor.collection 
     421            self._target = collection.resolve(self.of_kind, self.entity) 
    437422        return self._target 
    438423    target = property(target)