I can not agree that extending is "safe" as I've encountered another
problem with custom class name:
http://www.sqlalchemy.org/trac/browser/sqlalchemy/trunk/lib/sqlalchemy/sql/util.py#L145
And I guess it is not the last :(

I see, you propose not to extend class Column and write "a function
that creates instances" but it seems to me that this approach is not
good because it is not "pythonic", it is not "object-oriented"ly, it
is hard to write, support and extend.

Continuing experiments I created the following (ugly) code. Maybe it
will help someone with similar needs.

class CustomColumnMetaclass(sqlalchemy.Column.__metaclass__):
   def __init__(cls, clsname, bases, dct):
       cls.__name__ = sqlalchemy.Column.__name__
       cls.__visit_name__ = sqlalchemy.Column.__visit_name__
       super(CustomColumnMetaclass, cls).__init__(clsname, bases, dct)

class CustomColumn(sqlalchemy.Column):
   __metaclass__ = CustomColumnMetaclass

Btw, I still think that relying on class name is a bad way to do
things. What do you think Michael, how difficult it can be to rewrite
those pieces of code to use more OOP-like technics, particularly
explicitly define class properties (inheritable class properties!)
instead of doing things like eval("Annotated%s"  %
element.__class__.__name__)?

On Dec 7, 1:33 am, Michael Bayer <[EMAIL PROTECTED]> wrote:
> On Dec 6, 2008, at 4:27 PM, Angri wrote:
>
> > 1. What about another side-effects depending on clsname? Is it
> > actually safe to extend sqlalchemy.schema.Column, or it may have
> > unpredictable behavior similar to that i've encountered?
>
> The Column object is one of the most key classes in all of SQLAlchemy  
> and we do put it through some fairly intricate copy/proxy patterns  
> particularly when using the ORM.  Extending it should be "safe",  
> although this is usually not needed.   For custom creation patterns as  
> you're seeking here its more straightforward to build a creation  
> function, so that the resulting object is returned unchanged in its  
> type.
>
>
>
> > 2. (almost offtopic) Is 'exec' really need there? What's wrong with
> > closures?
>
> the visit step is called very intensively during statement compilation  
> so exec'ing the direct code instead of relying upon getattr() with a  
> composed name at runtime is an optimization to reduce function-call  
> and attribute-retrieval overhead.   Just as a point of reference I  
> tried rewriting our "visit" dispatcher in C, and my experiments showed  
> that using the exec approach you see there performs just as well -  
> though the time savings compared to a basic getattr() approach are  
> very small.
>
> Since you raised the issue, I went to try a different approach which  
> is probably the best possible approach without using exec, which is  
> this:
>
>          visit_name = cls.__dict__["__visit_name__"]
>          if isinstance(visit_name, str):
>              getter = operator.attrgetter("visit_%s" % visit_name)
>              def _compiler_dispatch(self, visitor, **kw):
>                  return getter(visitor)(self, **kw)
>          else:
>              def _compiler_dispatch(self, visitor, **kw):
>                  return getattr(visitor, 'visit_%s' %  
> self.__visit_name__)(self, **kw)
>
> Above, we use operator.attrgetter so that the string composition is  
> already handled, and the attrgetter itself is a native object which  
> performs as fast as direct access.   This change still adds a few  
> function calls per compile.  Our bench of a single select() compile  
> goes from 183 to 187, and two of the zoomark_orm tests fail past the  
> 5% threshhold, with tests three and four moving from 6623 to 6723  and  
> 23345 to 23861 function calls, respectively.  Which is an extremely  
> small amount, so its not a terribly big deal either way.  So the exec  
> approach is saving a tiny amount of call counts, but not necessarily  
> any actual time.  I'd be willing to scrap it if it continues to scare  
> other developers.
>
> The reason I'm at all comfortable with exec is that we're already  
> using 'exec' for decorators - its a technique used by the "decorators"  
> module (which I'd like to transition to at some point) to faithfully  
> represent the calling signature of a decorated function.
>
>
>
> > 3. Maybe I should send it to developers mailing list?
>
> either....devel is not very active.  though this is a pretty develop-y  
> subject...
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To post to this group, send email to sqlalchemy@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to