I agree that 3rd party backends should have a hook to provide their own customisations. I still think that the as_vendor approach is useful provided that the backend has a chance to register their customisations (where required - they still automatically use the default as_sql() method if there is no as_vendor method) at an appropriate time. I guess I don't really understand the particular issues with registering custom as_vendor implementations.
> Yes, I wasn't thinking about this case in my first mail, and I agree that this is a serious problem for the pure as_vendor() approach; it's not acceptable IMO to expect third-party database backends to monkeypatch their as_vendor() methods onto the built-in Function classes. Why is this not acceptable? I think I'm missing something. - Josh On Friday, 27 June 2014 21:04:28 UTC+10, Anssi Kääriäinen wrote: > > On Thursday, June 19, 2014 12:23:20 AM UTC+3, Carl Meyer wrote: >> >> On 06/18/2014 02:59 PM, Aymeric Augustin wrote: >> > 2014-06-18 19:18 GMT+02:00 Carl Meyer <ca...@oddbird.net >> > <mailto:ca...@oddbird.net>>: >> > >> > If you need a Function in your >> > project (whether provided by Django or by a third-party library), >> and >> > the Function doesn't natively support the database backend you're >> using, >> > you can simply subclass it, add the appropriate as_vendor method, >> and >> > use your subclass. >> > >> > >> > I was thinking about third-party database backends. How are they >> expected >> > to ship customised implementations of Functions included in Django? >> >> Yes, I wasn't thinking about this case in my first mail, and I agree >> that this is a serious problem for the pure as_vendor() approach; it's >> not acceptable IMO to expect third-party database backends to >> monkeypatch their as_vendor() methods onto the built-in Function classes. >> >> I think database backends should have a hook to override the SQL >> implementation of any given Function. I don't think this needs to imply >> pushing the default implementation of all Functions down into the >> database backend (that just makes life unnecessarily difficult for >> third-party Functions). >> > > This is possible to do by supplying a custom SQLCompiler class for the > backend, and overriding its .compile() method. > > Personally I don't see usage of as_vendor() as that problematic. Supplying > as_vendor in first DatabaseWrapper.__init__() should work. Yes, we are > dynamically altering the node's class. But we are just using the __dict__ > of the node to store backend specific implementation instead of using a > dictionary somewhere in the backend for the implementation. Using the > __dict__ has the advantage that inheritance works automatically. > > As multiple core developers have said they don't like as_vendor() for 3rd > party backend support it might be better to offer official hook for > altering the generated SQL. That is, change the SQLCompiler.compile() > method from > > def compile(self, node): > vendor_impl = getattr( > node, 'as_' + self.connection.vendor, None) > if vendor_impl: > return vendor_impl(self, self.connection) > else: > return node.as_sql(self, self.connection) > > to > > def compile(self, node): > ret = self.connection.compile(node) > if ret is not None: > return ret > vendor_impl = getattr( > node, 'as_' + self.connection.vendor, None) > if vendor_impl: > return vendor_impl(self, self.connection) > else: > return node.as_sql(self, self.connection) > > The main reason for offering a hook is that overriding SQLCompiler is a > bit problematic. There exists various subclasses of SQLCompiler, and the > backend needs to support those, too. > > - 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/9dcf210e-7683-470c-bc30-99ba98ae11c6%40googlegroups.com. For more options, visit https://groups.google.com/d/optout.