1

I have the next queries.

item = [item.export_simple()
            for item in session.query(Item)
                               .filter(and_(
                                       Item.companyId == company_id,
                                       or_(
                                           True if search == "" else None,
                                           or_(*[Item.name.like('%{0}%'.format(s)) for s in words]),
                                           or_(*[Item.code.like('%{0}%'.format(s)) for s in words])
                                            ))).order_by(Item.name)]

and this one.

if type == "code":
            src = [Item.code.like('%{0}%'.format(s)) for s in words]
        elif type == "name":
            src = [Item.name.like('%{0}%'.format(s)) for s in words]

 session.query(Item)
                    .filter(and_(
                        Item.companyId == company_id,
                        Item.typeItem == item_type,
                        or_(
                            True if search == "" else None,
                            or_(*src)
                        )))

In both cases i have * operator in or_() statement, and both queries work awesome, but i don´t know exactly why. This is the reference and this one

Community
  • 1
  • 1
Adrian Serna
  • 171
  • 3
  • 15

1 Answers1

5

This isn't something related to SQLAlchemy. This unpacks a list into comma-separated arguments, and is a brilliant Python feature. It's formally called the "single star" operator, but it's commonly refered to as the "splat" operator. This:

a = [1, 2, 3]
something(*a)

Is equivalent to this:

something(1, 2, 3)

So, in your first example, it's executing the list comprehension [Item.name.like('%{0}%'.format(s)) for s in words] and then unpacking its arguments into the or_ call.

For more information about this operator, refer to the Python documentation.

Aaron Christiansen
  • 11,584
  • 5
  • 52
  • 78
  • 1
    For googling purposes, I think it's important to mention that this is often referred to as the splat operator. – zephyr May 20 '16 at 20:07
  • Isn't it also true that when passing a *list or *tuple to something(*a) both get coerced into a tuple inside something()? – rp. May 22 '16 at 16:03
  • @rp. Can you give a code example please? – Aaron Christiansen May 22 '16 at 16:05
  • Code showing the coersion is in this question: http://stackoverflow.com/questions/37376674/does-pythons-splat-operator-coerce-lists-into-tuples – rp. May 22 '16 at 16:18