Правильный способ выполнения «НЕ ОТЛИЧАЕТСЯ» в SQLalchemy - PullRequest
0 голосов
/ 21 ноября 2018

У меня есть таблица с названием product и портирование этого SQL-запроса с psycopg2 на 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(), которую можно использовать как прямую замену «НЕ ОТЛИЧАЕТСЯ ОТ ...».Я реализовал этот код для преобразования запроса выбора в 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...