Changeset 342
- Timestamp:
- 06/18/08 18:37:18 (5 years ago)
- Location:
- elixir/trunk/elixir
- Files:
-
- 3 modified
-
__init__.py (modified) (3 diffs)
-
entity.py (modified) (8 diffs)
-
relationships.py (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
elixir/trunk/elixir/__init__.py
r334 r342 21 21 from sets import Set as set 22 22 23 import sys 23 24 import warnings 25 26 from py23compat import rsplit 27 24 28 import sqlalchemy 25 29 from sqlalchemy.types import * … … 93 97 # default entity collection 94 98 class AttributeEntityList(list): 99 _entities = {} 95 100 96 101 def __init__(self): … … 101 106 if key in self._entity_map: 102 107 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 103 126 self._entity_map[key] = entity 104 127 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 105 147 def __getattr__(self, key): 106 148 return self._entity_map.get(key) -
elixir/trunk/elixir/entity.py
r338 r342 10 10 11 11 import 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 12 from sqlalchemy import Table, Column, Integer, desc, ForeignKey, and_, \ 13 ForeignKeyConstraint 14 from sqlalchemy.orm import Query, MapperExtension, mapper, object_session, \ 15 EXT_CONTINUE, polymorphic_union 19 16 try: 20 17 from sqlalchemy.ext.sessioncontext import SessionContext … … 86 83 self.builders = [] 87 84 88 self.is_base = is_base(entity)89 85 self.parent = None 90 86 self.children = [] 91 87 92 88 for base in entity.__bases__: 93 if isinstance(base, EntityMeta) and not is_base(base):89 if isinstance(base, EntityMeta) and is_entity(base): 94 90 if self.parent: 95 91 raise Exception('%s entity inherits from several entities,' … … 278 274 self.entity.table = self.parent.table 279 275 280 # re-add the entity columns to the parent entity so that they281 # are added to the parent's table (whether the parent's table282 # 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). 283 279 for col in self.columns: 284 280 self.parent._descriptor.add_column(col) … … 655 651 return getattr(owner, self.attrname) 656 652 657 def is_ base(cls):653 def is_entity(cls): 658 654 """ 659 Scan bases classes to see if any is an instance of EntityMeta. If we660 don't find any, it means the current entity is a base class (like661 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). 662 658 """ 663 659 for base in cls.__bases__: 664 660 if isinstance(base, EntityMeta): 665 return False666 return True661 return True 662 return False 667 663 668 664 class EntityMeta(type): … … 672 668 for your entities (ie you don't want to use the provided 'Entity' class). 673 669 """ 674 _entities = {}675 670 676 671 def __init__(cls, name, bases, dict_): … … 679 674 # be registered in an entity collection, nor to have a table name and 680 675 # so on. 681 if is_base(cls):676 if not is_entity(cls): 682 677 return 683 684 # build a dict of entities for each frame where there are entities685 # defined686 caller_frame = sys._getframe(1)687 cid = cls._caller = id(caller_frame)688 caller_entities = EntityMeta._entities.setdefault(cid, {})689 caller_entities[name] = cls690 691 # Append all entities which are currently visible by the entity. This692 # will find more entities only if some of them where imported from693 # 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__] = entity697 678 698 679 # create the entity descriptor … … 772 753 #TODO: we might want to add all columns that will be available as 773 754 #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 the755 #rare usecase, as people will normally hit the query attribute before the 775 756 #column attributes, but still... 776 757 for name in ('c', 'table', 'mapper', 'query'): … … 1008 989 get = classmethod(get) 1009 990 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 327 327 ''' 328 328 329 import sys 330 329 331 from sqlalchemy import ForeignKeyConstraint, Column, \ 330 332 Table, and_ 331 333 from sqlalchemy.orm import relation, backref 334 from sqlalchemy.ext.associationproxy import association_proxy 335 336 import options 332 337 from elixir.statements import ClassMutator 333 338 from elixir.fields import Field 334 339 from elixir.properties import Property 335 340 from 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 342 342 343 343 __doc_all__ = [] … … 415 415 self.property = relation(self.target, **kwargs) 416 416 self.entity._descriptor.add_property(self.name, self.property) 417 417 418 418 def target(self): 419 419 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) 437 422 return self._target 438 423 target = property(target)
