to get this working, i had to add a line to clear the cache entry for
attr if the base argument was passed in:

    def entity(self, attr, schema=None, base=None):
        if base: del self._cache[attr]   # ADDED LINE
        try:
            t = self._cache[attr]
        except KeyError, ke:
            table = Table(attr, self._metadata, autoload=True,
autoload_with=self.bind, schema=schema or self.schema)
            if not table.primary_key.columns:
                raise PKNotFoundError('table %r does not have a
primary key defined [columns: %s]' % (attr, ','.join(table.c.keys())))
            if table.columns:
                t = _class_for_table(self.session, self.engine, table,
base or self.base)
            else:
                t = None
            self._cache[attr] = t
        return t

it works now no matter when it's called.  pretty neat.

On Nov 17, 1:19 pm, Michael Bayer <mike...@zzzcomputing.com> wrote:
> On Nov 17, 2010, at 4:05 PM, J wrote:
>
> > hmm... but i was thinking of having specialized methods for every
> > table/object.  am i missing something from your suggestion?  
>
> No, SqlSoup only offers the base class for all objects as an option.  Here's 
> a patch you can try:
>
> diff -r 67d8f4e2fcb9 lib/sqlalchemy/ext/sqlsoup.py
> --- a/lib/sqlalchemy/ext/sqlsoup.py     Wed Nov 17 10:55:10 2010 -0500
> +++ b/lib/sqlalchemy/ext/sqlsoup.py     Wed Nov 17 16:17:23 2010 -0500
> @@ -540,7 +540,7 @@
>          j = join(*args, **kwargs)
>          return self.map(j)
>
> -    def entity(self, attr, schema=None):
> +    def entity(self, attr, schema=None, base=None):
>          try:
>              t = self._cache[attr]
>          except KeyError, ke:
> @@ -548,7 +548,7 @@
>              if not table.primary_key.columns:
>                  raise PKNotFoundError('table %r does not have a primary key 
> defined [columns: %s]' % (attr, ','.join(table.c.keys())))
>              if table.columns:
> -                t = _class_for_table(self.session, self.engine, table, 
> self.base)
> +                t = _class_for_table(self.session, self.engine, table, base 
> or self.base)
>              else:
>                  t = None
>              self._cache[attr] = t
>
> mysoup.entity('mytable', base=MyBaseClass)
>
> > how would
> > you have a base class that would somehow specialize depending on the
> > child object?
>
> > i went ahead and executed my mixin idea by attacking the db._cache
> > dict with the mixins:
>
> > def __bind_mixins(db):
> >   for table_name,v in db._cache.items():
> >      # this is pretty retarded, just truncates last letter assuming
> > 's' plural
> >      mixin_name = table_name[:-1]
> >      try:
> >         # this is also pretty retarded.  __import__() didn't quite
> > work.
> >         # i'm thinking it was a circular import/runtime execution
> > order issue
> >         exec 'from mixins.%s import %s' % (mixin_name, mixin_name)
> >         mixin_cls = locals()[mixin_name]
> > db._cache[table_name].__bases__ += (mixin_cls,)
> >      except ImportError: pass
>
> > On Nov 17, 8:02 am, Michael Bayer <mike...@zzzcomputing.com> wrote:
> >> On Nov 17, 2010, at 4:23 AM, J wrote:
>
> >>> so i'm using sqlsoup to support a legacy db, and am thoroughly
> >>> enjoying it.  it was awesome setting up relationships and all that
> >>> even though the underlying db schema didn't have any foreign key
> >>> defines!
>
> >>> however, i'm at a point where i'd like to add some helper funcitons/
> >>> methods to some MappedFoo objects that sqlsoup likes to return.
>
> >>> i was thinking of using a mixin to add the extra functionality.  for
> >>> example:
>
> >>> # assume foo is a MappedFoo instance returned from sqlsoup already
> >>> class x:
> >>>   def bar(): print 'bar'
> >>> foo.__bases__ += (x,)
> >>> foo.bar() # prints 'bar' as expected
>
> >>> however, it would be super if there was some way to have the sqlsoup
> >>> getters already have this mixin or some overriding baseclass
> >>> configured... or some automated way of applying a mixin behind the
> >>> scenes.
>
> >> SqlSoup allows a "base" argument which will serve as the base class for 
> >> all generated classes:
>
> >>         SqlSoup(engine, base=MyClass)
>
> >> we should probably add the constructor and stuff to the docstrings.
>
> >>> thoughs?  thanks.
>
> >>> --
> >>> You received this message because you are subscribed to the Google Groups 
> >>> "sqlalchemy" group.
> >>> To post to this group, send email to sqlalch...@googlegroups.com.
> >>> To unsubscribe from this group, send email to 
> >>> sqlalchemy+unsubscr...@googlegroups.com.
> >>> For more options, visit this group 
> >>> athttp://groups.google.com/group/sqlalchemy?hl=en.
>
> > --
> > You received this message because you are subscribed to the Google Groups 
> > "sqlalchemy" group.
> > To post to this group, send email to sqlalch...@googlegroups.com.
> > To unsubscribe from this group, send email to 
> > sqlalchemy+unsubscr...@googlegroups.com.
> > For more options, visit this group 
> > athttp://groups.google.com/group/sqlalchemy?hl=en.

-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To post to this group, send email to sqlalch...@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.

Reply via email to