测试sqlalchemy选择对象中的where子句

时间:2018-06-21 15:21:42

标签: python unit-testing testing sqlalchemy

我正在尝试编写一些函数来构建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子句,但我无法使其正常工作。

1 个答案:

答案 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