1

我正在使用 PyPika(版本 0.37.6)创建要在 BigQuery 中使用的查询。我正在构建一个包含两个WITH子句的查询,一个子句依赖于另一个子句。由于我的应用程序的动态特性,我无法控制将这些WITH子句添加到查询中的顺序。

这是示例工作代码:

    a_alias = AliasedQuery("a")
    b_alias = AliasedQuery("b")
    a_subq = Query.select(Term.wrap_constant("1").as_("z")).select(Term.wrap_constant("2").as_("y"))
    b_subq = Query.from_(a_alias).select("z")

    q = Query.with_(a_subq, "a").from_(a_alias).select(a_alias.y)
    q = q.with_(b_subq, "b").from_(b_alias).select(b_alias.z)

    sql = q.get_sql(quote_char=None)

这会生成一个有效的查询:

WITH a AS (SELECT '1' z,'2' y) ,b AS (SELECT a.z FROM a) SELECT a.y,b.z FROM a,b

但是,如果我b WITH先添加子句,那么由于a尚未定义,结果查询:

WITH b AS (SELECT a.z FROM a), a AS (SELECT '1' z,'2' y) SELECT a.y,b.z FROM a,b

不起作用。由于 BigQuery 不支持WITH RECURSIVE,因此这不是我的选择。

有没有办法控制WITH子句的顺序?我_with在 QueryBuilder 中看到了列表(变量的类型q),但由于这是一个私有变量,我不想依赖它,尤其是新版本的 PyPika 可能不会以相同的方式运行。

我尝试这样做的一种方法是始终WITH在列表的开头插入第一个子句_with,如下所示: q._with.insert(0, q._with.pop()) 虽然这可行,但我想使用 PyPika 支持的方式来做到这一点。

在一个相关问题中,PyPika 中是否有一种支持的方式来查看已添加到选择列表或查询的其他部分的内容?我注意到q.selects成员变量,但selects不是公共文档的一部分。在使用q.selects我们项目的 Python 版本(3.6)时,使用实际上对我不起作用,即使它在 Python 3.7 中确实有效。我试图使用的代码是:

if any(field.name == "date" for field in q.selects if isinstance(field, Field))

我得到的错误如下:

    def __getitem__(self, item: slice) -> "BetweenCriterion":
         if not isinstance(item, slice): 
    >        raise TypeError("Field' object is not subscriptable")

预先感谢您的帮助。

4

1 回答 1

0

我不知道如何在调用后控制 WITH 子句的顺序query.with_()(除了已经提到的 hack)。结果,我重组了我的应用程序来解决这个问题。我现在query.with_()在建立查询的其余部分之前打电话。

这也使我的相关问题变得毫无意义,因为我不再需要查看我已经添加到查询中的内容。

于 2020-07-13T23:13:35.523 回答