So, anyway, I must implement BitAnd class? Or I can check if 'element.op == &' inside compile function?
чт, 19 апр. 2018 г., 16:31 Mike Bayer <mike...@zzzcomputing.com>: > On Thu, Apr 19, 2018 at 5:21 AM, Антонио Антуан <a.ch....@gmail.com> > wrote: > > Hi guys. > > > > Is there any mechanism in SQLAlchemy which allows to redefine operator > > compilation? I want to the same thing as already exists for functions. > > An example for functions: > > > > > > class IntDiv(GenericFunction): > > type = Integer > > package = 'adc_custom' > > name = 'div' > > identifier = 'div' > > > > > > @compiles(IntDiv) > > def visit_div_default(element, compiler, **kwargs): > > params = [compiler.process(c.self_group()) for c in > > element.clause_expr.element.get_children()] > > return '%s / %s' % (params[0], params[1]) > > > > > > @compiles(IntDiv, 'clickhouse') > > def visit_div_ch(element, compiler, **kwargs): > > return 'intDiv(%s)' % compiler.process(element.clause_expr.element) > > > > What I want to do: > > > > class BitAdd(CustomOp): > > pass > > > > @compiles(BitAdd) > > def visit_bit_add_default(element, compiler, **kwargs): > > return '%s & %s' % (element.left, element.right) > > > > > > @compiles(IntDiv, 'clickhouse') > > def visit_bit_add_ch(element, compiler, **kwargs): > > return 'bitAnd(%s, %s)' % (element.left, element.right) > > > > Statement looks like that: > > some_col.op('&')(some_int_flag) > > > > > > I understand that I can define generic function and use it instead of > > `.op('&')`, but at first I want to find another way. > > So in this case you are looking to override the compilation for > BinaryElement in any case since you want to run a function around them > in one case, that is the whole left/operator/right object. > > from sqlalchemy.sql.expression import BinaryExpression > @compiles(BinaryExpression, "clickhouse") > def visit_binary(element, compiler, **kw): > if isinstance(element.operator, BitAdd): > return "bitAnd(%s, %s)" % (compiler.process(element.left, > **kw), compiler.process(element.right, **kw)) > else: > return compiler.visit_binary(element, **kw) > > For the part where you want op('&') to be magic, it can't work that > way, though you can get at the '&' operator directly but you normally > need to use a subclass of Integer: > > > http://docs.sqlalchemy.org/en/latest/core/custom_types.html#redefining-and-creating-new-operators > > so here you'd be saying: > > from sqlalchemy import Integer > > class MyInt(Integer): > class comparator_factory(Integer.Comparator): > def __and__(self, other): > return BitAnd()(self.expr, other) > > then you'd use the MyInt datatype in your mappings where you want your > special operator to take place. > > If you want the base Integer to do this, you'd need to monkeypatch the > comparator, this is less recommended as it can cause surprises: > > > class comparator_factory_mixin(object): > def __and__(self, other): > return BitAnd()(self.expr, other) > > Integer.Comparator.__bases__ = (comparator_factory_mixin, ) + > Integer.Comparator.__bases__ > > > > > > > -- > > SQLAlchemy - > > The Python SQL Toolkit and Object Relational Mapper > > > > http://www.sqlalchemy.org/ > > > > To post example code, please provide an MCVE: Minimal, Complete, and > > Verifiable Example. See http://stackoverflow.com/help/mcve for a full > > description. > > --- > > You received this message because you are subscribed to the Google Groups > > "sqlalchemy" group. > > To unsubscribe from this group and stop receiving emails from it, send an > > email to sqlalchemy+unsubscr...@googlegroups.com. > > To post to this group, send email to sqlalchemy@googlegroups.com. > > Visit this group at https://groups.google.com/group/sqlalchemy. > > For more options, visit https://groups.google.com/d/optout. > > -- > SQLAlchemy - > The Python SQL Toolkit and Object Relational Mapper > > http://www.sqlalchemy.org/ > > To post example code, please provide an MCVE: Minimal, Complete, and > Verifiable Example. See http://stackoverflow.com/help/mcve for a full > description. > --- > You received this message because you are subscribed to the Google Groups > "sqlalchemy" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to sqlalchemy+unsubscr...@googlegroups.com. > To post to this group, send email to sqlalchemy@googlegroups.com. > Visit this group at https://groups.google.com/group/sqlalchemy. > For more options, visit https://groups.google.com/d/optout. > -- Антон -- SQLAlchemy - The Python SQL Toolkit and Object Relational Mapper http://www.sqlalchemy.org/ To post example code, please provide an MCVE: Minimal, Complete, and Verifiable Example. See http://stackoverflow.com/help/mcve for a full description. --- You received this message because you are subscribed to the Google Groups "sqlalchemy" group. To unsubscribe from this group and stop receiving emails from it, send an email to sqlalchemy+unsubscr...@googlegroups.com. To post to this group, send email to sqlalchemy@googlegroups.com. Visit this group at https://groups.google.com/group/sqlalchemy. For more options, visit https://groups.google.com/d/optout.