SQL到SQLAlchemy的翻译

时间:2018-03-17 19:02:36

标签: python mysql sql sqlalchemy

我有一个有点奇怪的查询,它获取父表中所有在相应子表中没有匹配项的项。

如果可能,id喜欢将其转换为SQLAlchemy查询。但我不知道怎么做。我可以做基本的获取和过滤,但到目前为止,这个超出了我的经验。非常感谢您的帮助。

class customerTranslations(Base):
    """parent table. holds customer names"""
    __tablename__ = 'customer_translation'

    id = Column(Integer, primary_key=True)

class customerEmails(Base):
    """child table. hold emails for customers in translation table"""
    __tablename__ = 'customer_emails'

    id = Column(Integer, primary_key=True)
    parent_id = Column(Integer, ForeignKey('customer_translation.id'))

我想建立:

SELECT * FROM customer_translation 
WHERE id NOT IN (SELECT parent_id FROM customer_emails)

1 个答案:

答案 0 :(得分:1)

你有一个子查询,所以先创建一个:

all_emails_stmnt = session.query(customerEmails.parent_id).subquery()

然后您可以使用它来过滤您的其他表:

translations_with_no_email = session.query(customerTranslations).filter(
    ~customerTranslations.id.in_(all_emails_stmnt))

这会生成相同的SQL(但扩展了所有列名,而不是使用*,然后ORM可以创建对象):

>>> all_emails_stmnt = session.query(customerEmails.parent_id).subquery()
>>> print(all_emails_stmnt)
SELECT customer_emails.parent_id
FROM customer_emails
>>> translations_with_no_email = session.query(customerTranslations).filter(
...     ~customerTranslations.id.in_(all_emails_stmnt))
>>> print(translations_with_no_email)
SELECT customer_translation.id AS customer_translation_id
FROM customer_translation
WHERE customer_translation.id NOT IN (SELECT customer_emails.parent_id
FROM customer_emails)

您也可以使用NOT EXISTS

from sqlalchemy.sql import exists

has_no_email_stmnt = ~exists().where(customerTranslations.id == customerEmails.parent_id)
translations_with_no_email = session.query(customerTranslations).filter(has_no_email_stmnt)

或者,如果您对指向名为customerTranslations的电子邮件的emails类进行反向引用,请在关系上使用.any()并反转:

 session.query(customerTranslations).filter(
    ~customerTranslations.emails.any())

早在2010年NOT EXISTS was a little slower on MySQL,但您可能想重新评估是否仍然如此。