Changeset 426

Show
Ignore:
Timestamp:
12/05/08 15:02:36 (5 years ago)
Author:
ged
Message:

- Fixed filter argument on OneToMany relationship leaking the filter to the

unfiltered relationship. Doh!!!

- added preliminary code for filter on ManyToMany (but see ticket #68 comment)
- renamed M2M.secondary_table to M2M.table

Location:
elixir/trunk
Files:
2 modified

Legend:

Unmodified
Added
Removed
  • elixir/trunk/CHANGES

    r425 r426  
    7575- Added workaround for an odd mod_python behavior (class.__module__ returns a 
    7676  weird name which is not in sys.modules). 
     77- Fixed filter argument on OneToMany relationship leaking the filter to the 
     78  unfiltered relationship. 
    7779 
    78800.6.1 - 2008-08-18 
  • elixir/trunk/elixir/relationships.py

    r421 r426  
    455455 
    456456        # transform callable arguments 
    457         for arg in ('primaryjoin', 'secondaryjoin', 'remote_side', 'filter', 
     457        for arg in ('primaryjoin', 'secondaryjoin', 'remote_side', 
    458458                    'foreign_keys'): 
    459459            kwarg = kwargs.get(arg, None) 
     
    749749        self.filter = filter 
    750750        if filter is not None: 
    751             # We set viewonly to True by default for filtered relationship, 
     751            # We set viewonly to True by default for filtered relationships, 
    752752            # unless manually overridden. 
    753753            # This is not strictly necessary, as SQLAlchemy allows non viewonly 
     
    793793            kwargs['remote_side'] = self.inverse.foreign_key 
    794794 
     795        # Contrary to ManyToMany relationships, we need to specify the join 
     796        # clauses even if this relationship is not self-referencial because 
     797        # there could be several ManyToOne from the target class to us. 
    795798        joinclauses = self.inverse.primaryjoin_clauses 
    796799        if self.filter: 
    797             joinclauses.append(self.filter(self.target.table.c)) 
     800            # We need to make a copy of the joinclauses, to not add the filter 
     801            # on the backref 
     802            joinclauses = joinclauses[:] + [self.filter(self.target.table.c)] 
    798803        if joinclauses: 
    799804            kwargs['primaryjoin'] = and_(*joinclauses) 
     
    816821                 table=None, schema=None, 
    817822                 column_format=None, 
     823                 filter=None, 
    818824                 *args, **kwargs): 
    819825        self.user_tablename = tablename 
     
    829835        self.onupdate = onupdate 
    830836 
    831         self.secondary_table = table 
     837        self.table = table 
    832838        self.schema = schema 
    833839 
     
    841847        self.column_format = column_format or options.M2MCOL_NAMEFORMAT 
    842848 
     849        self.filter = filter 
     850        if filter is not None: 
     851            # We set viewonly to True by default for filtered relationships, 
     852            # unless manually overridden. 
     853            if 'viewonly' not in kwargs: 
     854                kwargs['viewonly'] = True 
     855 
    843856        self.primaryjoin_clauses = [] 
    844857        self.secondaryjoin_clauses = [] 
     
    846859        super(ManyToMany, self).__init__(of_kind, *args, **kwargs) 
    847860 
     861    def get_table(self): 
     862        warnings.warn("The secondary_table attribute on ManyToMany objects is" 
     863                      "deprecated", DeprecationWarning, stacklevel=2) 
     864        return self.table 
     865    secondary_table = property(get_table) 
     866 
    848867    def match_type_of(self, other): 
    849868        return isinstance(other, ManyToMany) 
    850869 
    851870    def create_tables(self): 
    852         if self.secondary_table: 
     871        if self.table: 
    853872            if 'primaryjoin' not in self.kwargs or \ 
    854873               'secondaryjoin' not in self.kwargs: 
     
    857876 
    858877        if self.inverse: 
    859             if self.inverse.secondary_table: 
    860                 self.secondary_table = self.inverse.secondary_table 
     878            if self.inverse.table: 
     879                self.table = self.inverse.table 
    861880                self.primaryjoin_clauses = self.inverse.secondaryjoin_clauses 
    862881                self.secondaryjoin_clauses = self.inverse.primaryjoin_clauses 
     
    927946                       self.target.__name__)) 
    928947 
    929             self.secondary_table = Table(tablename, e1_desc.metadata, 
    930                                          autoload=True) 
     948            self.table = Table(tablename, e1_desc.metadata, autoload=True) 
    931949            if 'primaryjoin' not in self.kwargs or \ 
    932950               'secondaryjoin' not in self.kwargs: 
     
    9981016            args = columns + constraints 
    9991017 
    1000             self.secondary_table = Table(tablename, e1_desc.metadata, 
    1001                                          schema=schema, *args) 
     1018            self.table = Table(tablename, e1_desc.metadata, 
     1019                               schema=schema, *args) 
    10021020            if DEBUG: 
    1003                 print self.secondary_table.repr2() 
     1021                print self.table.repr2() 
    10041022 
    10051023    def _build_join_clauses(self): 
     
    10211039 
    10221040            self.primaryjoin_clauses, self.secondaryjoin_clauses = \ 
    1023                 _get_join_clauses(self.secondary_table, 
     1041                _get_join_clauses(self.table, 
    10241042                                  self.local_colname, self.remote_colname, 
    10251043                                  self.entity.table) 
    10261044 
    10271045    def get_prop_kwargs(self): 
    1028         kwargs = {'secondary': self.secondary_table, 
     1046        kwargs = {'secondary': self.table, 
    10291047                  'uselist': self.uselist} 
    10301048 
    1031         if self.target is self.entity: 
     1049        if self.filter: 
     1050            # we need to make a copy of the joinclauses 
     1051            secondaryjoin_clauses = self.secondaryjoin_clauses[:] + \ 
     1052                                    [self.filter(self.target.table.c)] 
     1053        else: 
     1054            secondaryjoin_clauses = self.secondaryjoin_clauses 
     1055 
     1056        if self.target is self.entity or self.filter: 
    10321057            kwargs['primaryjoin'] = and_(*self.primaryjoin_clauses) 
    1033             kwargs['secondaryjoin'] = and_(*self.secondaryjoin_clauses) 
     1058            kwargs['secondaryjoin'] = and_(*secondaryjoin_clauses) 
    10341059 
    10351060        kwargs.update(self.kwargs)