2

我在 Python 中使用 SQLObject ORM,并且我希望能够以与我相同的方式迭代(行对象的)生成器Table.select(...),但是我可以从执行此方法调用中得到的限制太严格,即使使用filter().

我希望以这种方式从 SQL 查询中获得相同的结果:

SELECT TableB.column_x, TableA.*
FROM TableA
INNER JOIN TableB
ON TableA.column_y = TableB.column_z;

我知道如何使用 SQLBuilder 来获得这个确切的查询:

columns = [TableB.q.column_x, TableA.q.id]  + 
  [getattr(TableA.q, col.name) for col in TableA.sqlmeta.columnList]
inner_join = sqlbuilder.INNERJOINOn(
  table1=TableA,
  table2=TableB,
  on_condition=(TableA.column_y==TableB.column_z),
)
select = sqlbuilder.sqlbuilder.Select(items=columns, join=inner_join)

从那里我可以执行这个查询:

conn = TableA._connection
rows = conn.queryAll(conn.sqlrepr(select))

但这会返回一个元组列表,而不是一个等价的生成器,就像你做的那样Table.select(...).filter(...)

这是“restore_defaults”端点的一部分,我需要恢复(默认的,只有默认的)行,TableA我需要查看哪些默认行仍然存在,并在将所有默认行插入之前删除它们TableA而不会覆盖/删除任何可能由用户创建的额外自定义行。换句话说,这是一个特定的要求,我确实需要使用上面 SQL 查询中的扩充表。

我意识到我可以使用返回的元组(甚至用它们制作临时字典)来进行这些检查并更新字典,但是有没有更好的方法来从 SQLObject 获得直接交互性,你可以通过定期select()调用获得?

(我们仅限于 Python 2.4,但我认为这不会有太大的不同)

4

1 回答 1

2
  1. 高级 API(SQLObject 继承的类)可以一次查询多个表(联接),但结果始终是 SQLObject 实例的列表,因此只有一个类的属性可以立即使用。常见问题解答中对此进行了解释。您可以声明一对多或多对多关系并访问其他表的属性;SQLObject 将获取行并将它们自动转换为 SQLObject 实例。

  2. 更正: SQLObject.select() 不返回生成器,它返回迭代器,即迭代类的实例。更准确地说,SQLObject.select() 产生一个SelectResults类的实例,该实例在被迭代时产生一个 Iteration 类的实例,该实例在调用其 next() 方法(它是迭代器!)时获取结果并将它们传递回用户。

  3. 唉,迭代只适用于 SelectResults。它不适用于 SQLBuilder 的查询。

于 2017-05-16T21:47:47.363 回答