Changeset 6

Show
Ignore:
Timestamp:
01/26/07 18:19:10 (6 years ago)
Author:
ged
Message:

- implemented the generation and use of primaryjoins for

belongs_to/has_one/has_many relationships. This is needed to allow
more than one belongs_to relation between two entities

- fixed a small bug to allow the same for has_and_belongs_to_many relations.
- added unit tests to test for those situations


Location:
supermodel/trunk/supermodel
Files:
1 added
1 modified

Legend:

Unmodified
Added
Removed
  • supermodel/trunk/supermodel/relationships.py

    r5 r6  
    159159         
    160160        self.foreign_key = [] 
     161        self.primaryjoin_clauses = list() 
     162 
    161163        for key in target_desc.primary_keys: 
    162             keycol = key.column 
    163             refcol = target_desc.tablename + '.' + keycol.name 
     164            pk_col = key.column 
     165            refcol = target_desc.tablename + '.' + pk_col.name 
    164166            #CHECKME: why do we use a Field here instead of directly using a  
    165167            # Column 
    166             field = Field(keycol.type, colname=self.name + '_' + keycol.name, 
     168            field = Field(pk_col.type, colname=self.name + '_' + pk_col.name, 
    167169                          index=True) 
    168170             
     
    171173            columns.append(field.column.name) 
    172174            source_desc.add_field(field) 
     175 
     176            # build up the primary join. This is needed when you have several 
     177            # belongs_to relations between two objects 
     178            self.primaryjoin_clauses.append(field.column == pk_col) 
    173179         
    174180        # TODO: better constraint-naming? 
     
    184190            cols = [k.column for k in self.target._descriptor.primary_keys] 
    185191            kwargs['remote_side'] = cols 
     192 
     193        kwargs['primaryjoin'] = and_(*self.primaryjoin_clauses) 
    186194         
    187195        #CHECKME: is this of any use? 
     
    211219                                        for f in self.inverse.foreign_key] 
    212220         
     221        kwargs['primaryjoin'] = and_(*self.inverse.primaryjoin_clauses) 
    213222        #CHECKME: is this of any use? 
    214223#        kwargs['backref'] = self.inverse.name 
     
    230239            if self.inverse.secondary: 
    231240                self.secondary = self.inverse.secondary 
     241                self.primaryjoin_clauses = self.inverse.secondaryjoin_clauses 
     242                self.secondaryjoin_clauses = self.inverse.primaryjoin_clauses 
    232243 
    233244        if not self.secondary: 
     
    242253            # case. I think it's also usefull when you have several many-to-many 
    243254            # relations between the same objects. I'll have to test that... 
     255            # no it's not since the tables are different. It would only if the 
     256            # tables where the same, but I'm not sure if it has some sense to be 
     257            # in that situation. 
    244258#            if self.entity is self.target: 
    245259#                print "many2many self ref detected" 
    246             self.primary_clauses = list() 
    247             self.secondary_clauses = list() 
     260            self.primaryjoin_clauses = list() 
     261            self.secondaryjoin_clauses = list() 
    248262 
    249263            for desc, join_name in ((e1_desc, 'primary'),  
     
    279293 
    280294                    # build join clauses 
    281                     getattr(self, join_name+'_clauses').append(col == pk_col) 
     295                    join_list = getattr(self, join_name+'join_clauses') 
     296                    join_list.append(col == pk_col) 
    282297                 
    283298                # TODO: better constraint-naming? 
     
    306321        kwargs = self.kwargs 
    307322 
    308         if self.entity is self.target: 
    309             kwargs['primaryjoin'] = and_(*self.primary_clauses) 
    310             kwargs['secondaryjoin'] = and_(*self.secondary_clauses) 
     323        if self.target is self.entity: 
     324            kwargs['primaryjoin'] = and_(*self.primaryjoin_clauses) 
     325            kwargs['secondaryjoin'] = and_(*self.secondaryjoin_clauses) 
    311326 
    312327        m = self.entity.mapper