Monkey patching is not really an API hook. It's what non-core code is forced to do when the core is not flexible enough to support what it needs. If this is the chosen route, which is the way it appears to be heading, then at least try to hide the fact that it's a monkey patch and mimic SQLAlchemy [1] with a decorator, or some type of register method.
I'm on the fence about whether I'd even use a monkey patch mechanism, instead of defining my own compile() for each of the SQLCompilers; DatabaseOperations.compile_node(self, compiler, node) would be better than overriding each compile. To me, it seems much more elegant to duck type the nodes as they're being compiled, instead of a giant import and monkey patch setup function. Regards, Michael Manfre [1] http://docs.sqlalchemy.org/en/rel_0_9/core/compiler.html On Tue, Jul 1, 2014 at 11:32 AM, Anssi Kääriäinen <anssi.kaariai...@thl.fi> wrote: > On Tue, 2014-07-01 at 17:49 +0300, Shai Berger wrote: > > > I think we can reach very similar results, with a much nicer API, by > letting > > the backends just override the function classes. > > The backend specific class must be instantiated at query compile time. > How is the data contained in the original class copied to the overriding > class? One possibility is to copy the original instance's __dict__ to > the overriding class. > > Also, "if the attribute has an attribute named like the function class" > isn't good, clashes between plain class names is expected. The overrides > could be a dictionary of original class -> overriding class. So, > something like this: > > class BackendLower(models.Lower): > def __init__(self, from_node): > # The hacky way > self.__dict__ = from_node.__dict__ > > def as_sql(self, qn, connection): > .... > overrides = {models.Lower: BackendLower} > > And compiler.compile() would look something like this: > > if node.__class__ in connection.overrides: > return connection.overrides[node.__class__](node).as_sql(...) > else: > return node.as_sql(...) > > Using the above way there is no need to alter classes dynamically. On > the other hand, copying data from the original class to the implementing > class can be risky (circular dependencies for example), and it is a bit > more expensive. Still, inheritance will not work like with as_vendor(), > but I am not sure how common subclasses without custom as_sql() are. > > - Anssi > > -- > You received this message because you are subscribed to the Google Groups > "Django developers" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to django-developers+unsubscr...@googlegroups.com. > To post to this group, send email to django-developers@googlegroups.com. > Visit this group at http://groups.google.com/group/django-developers. > To view this discussion on the web visit > https://groups.google.com/d/msgid/django-developers/1404228748.9408.189.camel%40TTY32 > . > For more options, visit https://groups.google.com/d/optout. > -- You received this message because you are subscribed to the Google Groups "Django developers" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-developers+unsubscr...@googlegroups.com. To post to this group, send email to django-developers@googlegroups.com. Visit this group at http://groups.google.com/group/django-developers. To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/CAGdCwBt5w_O-UqeOrnn%3D7JOHUqvt9a48eWQ7rsPkp0NibRd9zA%40mail.gmail.com. For more options, visit https://groups.google.com/d/optout.