我正在尝试编写一些函数来构建sqlalchemy select语句。例如:
import sqlalchemy as sa
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
metadata = Base.metadata
t_test = sa.Table(
'test', metadata,
sa.Column('col_1', sa.Text),
sa.Column('col_2', sa.Float)
)
def create_test_select():
sa_select = sa.select([t_test.c.col_1, t_test.c.col_2])
return sa_select
def add_test_col1_where_clause(sa_select, x ):
sa_select = sa_select.where(t_test.c.col_1 == x)
return sa_select
我想测试这些功能。
要测试create_test_select
,我会写类似
class Test(unittest.TestCase):
def test(self):
self.assertIn('col1', create_test_select().columns)
self.assertIn('col2', create_test_select().columns)
如何测试功能add_test_col1_where_clause
?我想知道它为select添加了正确的where子句。我最初的想法是检查sqlachemy select对象中的where子句,但我无法使其正常工作。
答案 0 :(得分:2)
SQLAlchemy不会直接公开select的where子句部分;毕竟不是所有的SELECT语句都有一个。此外,该子句可能变得相当复杂。就我个人而言,我只会在集成测试中测试这些表达式,并且只能确保返回正确的数据。
SQLAlchemy确实为您提供了访问对象树的工具,尽管文档不足。您可以使用它来提取树中的所有比较,因此<left> <op> <right>
和left
是 columns元素
right
from sqlalchemy.sql import visitors, ColumnElement
def comparison_visitor(expr, callback):
"""Finds all binary operators, and calls callback(op, left, right)"""
def visit_binary(op):
callback(op, op.left, op.right)
# visit each expr element, but for select clauses, ignore the column collection
visitors.traverse(expr, {'column_collections': False}, {'binary': visit_binary})
遍历任何SQLAlchemy表达式(通过反复调用对象的ColumnClause.get_children()
method,并将作为第二个参数给出的映射传递给visitors.traverse()
),并调用与每个对象的traverse()
属性。 __visit_name__
个对象的访问名称为BinaryClause
。
然后可以使用它来测试是否存在特定条件:
binary