Sqlalchemy + elixir: как запросить отношения с ManyToMany? - PullRequest
1 голос
/ 11 мая 2010

Я использую sqlalchemy с Elixir и у меня возникают проблемы при попытке сделать запрос ..

У меня есть 2 сущности, Customer и CustomerList, со связями многие ко многим.

customer_lists_customers_table = Table('customer_lists_customers', 
                      metadata,
                      Column('id', Integer, primary_key=True),
                      Column('customer_list_id', Integer, ForeignKey("customer_lists.id")),
                      Column('customer_id', Integer, ForeignKey("customers.id")))

class Customer(Entity):
  [...]
  customer_lists = ManyToMany('CustomerList', table=customer_lists_customers_table)

class CustomerList(Entity):
  [...]

  customers = ManyToMany('Customer', table=customer_lists_customers_table)

Я пытаюсь найти CustomerList с каким-либо клиентом:

customer = [...]
CustomerList.query.filter_by(customers.contains(customer)).all()

Но я получаю ошибку: NameError:

глобальное имя 'customer' не определено

клиенты, похоже, не связаны с полями сущностей, есть специальная форма запроса для работы со связями (или связями ManyToMany)?

Спасибо

Ответы [ 3 ]

1 голос
/ 11 мая 2010

Вы можете использовать обычный фильтр: query.filter(CustomerList.customers.contains(customer)).См. Документацию SQLAlchemy для большего количества примеров.Это фактически filter_by, это особый случай.Сокращение query.filter_by(**kwargs) работает только для простых сравнений на равенство.Под крышкой query.filter_by(foo="bar", baz=42) делегируется эквивалент query.filter(and_(MyClass.foo == "bar", MyClass.baz == 42)).(На самом деле есть немного больше магии, чтобы выяснить, какое свойство вы имели в виду, у вас много сущностей, но оно все еще использует простое делегирование)

1 голос
/ 11 мая 2010

Внимательно прочитайте сообщение об ошибке, оно указывает на источник проблемы. Ты имел ввиду CustomerList.query.filter_by(CustomerList.customers.contains(customer)).all()

Обновление : при использовании декларативного определения вы можете использовать только что определенное отношение в class scope, но эти свойства не видны вне класса:

class MyClass(object):
    prop1 = 'somevalue'
    prop2 = prop1.upper() # prop1 is visible here

val2 = MyClass.prop1 # This is OK    

val1 = prop1.lower() # And this will raise NameError, since there is no 
                     # variable `prop1` is global scope
0 голосов
/ 11 мая 2010

CustomerList.query.filter_by(CustomerList.customers.contains(customer)).all() должно работать нормально.

...