在SQLalchemy中执行“ IS NOT DISTINCT FROM”的正确方法

时间:2018-11-21 09:16:32

标签: python sqlalchemy

我有一个名为product的表,并将带有psycopg2的SQL查询移植到SQLalchemy。

cur.execute("SELECT id FROM product WHERE pid=%s AND product IS NOT DISTINCT FROM %s AND version IS NOT DISTINCT FROM %s AND build IS NOT DISTINCT FROM %s", (parent_id, item.get("product", None), item.get("version", None), item.get("build", None)))
product_id = cur.fetchone()

我发现SQLalchemy具有函数isnot_distinct_from(),可以直接替代“ IS NOT DISTINCT FROM ...”。 我实现了这段代码,将选择查询转换为sqlalchemy.session.query()

# Enhancing SQLalchemy standard class with generation of pure text SQL
class Query(_Query):
    def to_sql(self):
        dialect = self.session.bind.dialect
        return str(self.statement.compile(dialect=dialect))

    def __init__(self, entities, session):
        super().__init__(entities, session)
        print(self.to_sql())

def generate_product_table(base):
    class product(base):
        __tablename__ = "product"
        id = Column('id', Integer, primary_key=True)
        pid = Column('pid', Integer)
        url = Column('url', VARCHAR(4096), nullable=False)
        product = Column('product', VARCHAR(4096), nullable=True)
        version = Column('version', VARCHAR(4096), nullable=True)
        build = Column('build', VARCHAR(4096), nullable=True)
        date = Column('date', DateTime(timezone=False), server_default=func.now(), nullable=False)

    return product

class SomeClass():
    def create_tables(self):
        self.Product = generate_product_table(self.basemodel)
        self.basemodel.metadata.create_all(bind=self.engine)

    def some_method(self, item, parent_id):
        self.create_tables()
        # Here we have already engine and session initialized
        product_id = self.session.query(
            self.Product # <--- error is here from Traceback
        ).filter(
            self.Product.pid == parent_id
        ).filter(and_(
            self.Product.product.isnot_distinct_from(item.get("product", None)))
        ).filter(and_(
            self.Product.version.isnot_distinct_from(item.get("version", None)))
        ).filter(and_(
            self.Product.build.isnot_distinct_from(item.get("build", None)))
        ).options(load_only("id")).one_or_none()

        if not product_id:
            p.url = item["url"]

同时无法产生此错误:

Traceback (most recent call last):
File "example.py", line 20, in some_method
   self.Product
File "sqlalchemy/orm/session.py", line 1362, in query
   return self._query_cls(entities, self, **kwargs)
TypeError: 'str' object is not callable

0 个答案:

没有答案
相关问题