Changeset 432 for elixir/trunk

Show
Ignore:
Timestamp:
12/17/08 13:45:49 (3 years ago)
Author:
ged
Message:

- added test for the with_polymorphic mapper argument (closes #79).
- made manually defined mapper options take precedence over Elixir-generated

ones. Not very useful yet since most are expecting Column objects.

- we do not specify inherit_condition at all anymore since SA apparently

computes it correctly now, at least in 0.4.8+

- added doctrings on EntityBase's get_by and get methods

Location:
elixir/trunk
Files:
2 modified

Legend:

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

    r428 r432  
    234234                    # they are added to the parent's table (whether the 
    235235                    # parent's table is already setup or not). 
    236                     for col in self.columns: 
     236                    for col in self._columns: 
    237237                        self.parent._descriptor.add_column(col) 
    238238                    for constraint in self.constraints: 
     
    367367        # sqlalchemy/test/orm/inheritance/concrete.py 
    368368        # this should be added along other 
    369         kwargs = self.mapper_options 
     369        kwargs = {} 
    370370        if self.order_by: 
    371371            kwargs['order_by'] = self.translate_order_by(self.order_by) 
     
    379379                # non-polymorphic concrete doesn't need this 
    380380                kwargs['inherits'] = self.parent.mapper 
    381  
    382             if self.inheritance == 'multi' and self.parent: 
    383                 col_pairs = zip(self.primary_keys, 
    384                                 self.parent._descriptor.primary_keys) 
    385                 kwargs['inherit_condition'] = \ 
    386                     and_(*[pc == c for c, pc in col_pairs]) 
    387381 
    388382            if self.polymorphic: 
     
    409403                            self.get_column(self.polymorphic) 
    410404 
    411                     #TODO: this is an optimization, and it breaks the multi 
    412                     # table polymorphic inheritance test with a relation. 
    413                     # So I turn it off for now. We might want to provide an 
    414                     # option to turn it on. 
    415 #                    if self.inheritance == 'multi': 
    416 #                        children = self._get_children() 
    417 #                        join = self.entity.table 
    418 #                        for child in children: 
    419 #                            join = join.outerjoin(child.table) 
    420 #                        kwargs['select_table'] = join 
    421  
    422405                if self.children or self.parent: 
    423406                    kwargs['polymorphic_identity'] = self.identity 
     
    425408                if self.parent and self.inheritance == 'concrete': 
    426409                    kwargs['concrete'] = True 
     410 
     411        if self.parent and self.inheritance == 'single': 
     412            args = [] 
     413        else: 
     414            args = [self.entity.table] 
     415 
     416        # let user-defined kwargs override Elixir-generated ones, though that's 
     417        # not very usefull since most of them expect Column instances. 
     418        kwargs.update(self.mapper_options) 
    427419 
    428420        #TODO: document this! 
     
    431423            kwargs['primary_key'] = [getattr(cols, colname) for 
    432424                colname in kwargs['primary_key']] 
    433  
    434         if self.parent and self.inheritance == 'single': 
    435             args = [] 
    436         else: 
    437             args = [self.entity.table] 
    438425 
    439426        # do the mapping 
     
    596583 
    597584    def columns(self): 
    598         #FIXME: this would be more correct but it breaks inheritance, so I'll 
    599         # use the old test for now. 
    600 #        if self.entity.table: 
    601         if self.autoload: 
     585        if self.entity.table: 
    602586            return self.entity.table.columns 
    603587        else: 
     
    10891073    # query methods 
    10901074    def get_by(cls, *args, **kwargs): 
     1075        """ 
     1076        Returns the first instance of this class matching the given criteria. 
     1077        This is equivalent to: 
     1078        session.query(MyClass).filter_by(...).first() 
     1079        """ 
    10911080        return cls.query.filter_by(*args, **kwargs).first() 
    10921081    get_by = classmethod(get_by) 
    10931082 
    10941083    def get(cls, *args, **kwargs): 
     1084        """ 
     1085        Return the instance of this class based on the given identifier, 
     1086        or None if not found. This is equivalent to: 
     1087        session.query(MyClass).get(...) 
     1088        """ 
    10951089        return cls.query.get(*args, **kwargs) 
    10961090    get = classmethod(get) 
  • elixir/trunk/tests/test_inherit.py

    r424 r432  
    129129 
    130130    def test_inverse_matching_on_parent(self): 
    131         options_defaults['inheritance'] = 'multi' 
    132  
    133131        class Person(Entity): 
    134132            using_options(inheritance='multi') 
    135  
    136133            name = Field(UnicodeText) 
    137134 
     
    143140        class Child(Person): 
    144141            using_options(inheritance='multi') 
    145  
    146142            parents = ManyToMany('Parent', tablename='child_parent', 
    147143                                 inverse='childs') 
    148144 
    149145        setup_all() 
     146 
     147    def test_multitable_polymorphic_load(self): 
     148        class A(Entity): 
     149            using_options(inheritance='multi') 
     150            # we want to load children's specific data along the parent (A) 
     151            # data when querying the parent. If we don't specify this, the 
     152            # children data is loaded lazily 
     153            using_mapper_options(with_polymorphic='*') 
     154            name = Field(String(50)) 
     155 
     156        class B(A): 
     157            using_options(inheritance='multi') 
     158            data = Field(String(50)) 
     159            some_c = ManyToOne('C') 
     160 
     161        class C(A): 
     162            using_options(inheritance='multi') 
     163 
     164            data = Field(String(50)) 
     165            many_b = OneToMany('B') 
     166        setup_all(True) 
     167        a1 = A(name='a1') 
     168        c1 = C(name='c1', data="c") 
     169        b1 = B(name='b1', data="b", some_c=c1) 
     170 
     171        session.commit() 
     172        session.clear() 
     173 
     174        for a in A.query.all(): 
     175            if isinstance(a, (B, C)): 
     176                assert 'data' in a.__dict__ 
    150177 
    151178    def test_singletable_inheritance(self):