繁体   English   中英

如果它们相同,我如何比较两个 SQLAlchemy 查询?

[英]How can I compare two SQLAlchemy queries if they are the same?

我有一个 function 返回 SQLAlchemy 查询 object 并且我想测试这个 ZC1C425268E68384F1AB4A 查询。

例如:

import sqlalchemy

metadata = sqlalchemy.MetaData()
users = sqlalchemy.Table(
    "users",
    metadata,
    sqlalchemy.Column("email", sqlalchemy.String(255), nullable=False, unique=True),
    sqlalchemy.Column("username", sqlalchemy.String(50), nullable=False, unique=True),
)

def select_first_users(n):
    return users.select().limit(n)

def test_queries_are_equal(self):
    expected_query = users.select().limit(10)
    assert select_first_users(10) == expected_query  # fails here
    assert select_first_users(10).compare(expected_query)  # fails here too

我不知道如何比较两个查询是否相等。 ==在这里不起作用,因为据我所知,这些对象没有定义__eq__方法,因此它按 memory 中的地址比较对象并且肯定会失败。 compare方法is比较。

我看到的唯一解决方案是:

assert str(q1.compile()) == str(q2.compile())

,但它很奇怪并且包含占位符而不是实际值。

那么如何比较两个 SQLAlchemy 查询是否相等?

我使用 Python 3.7.4, SQLAlchemy==1.3.10

编译时有一个参数 function 可以解决占位符问题 query.compile(compile_kwargs={"literal_binds": True}),所以不是

SELECT users.email,
       users.username
FROM users
LIMIT :param_1

你得到

SELECT users.email,
       users.username
FROM users
LIMIT 10

所以我认为你可以做这样的事情

import sqlparse

def format_query(query):
    return sqlparse.format(str(query.compile(compile_kwargs={"literal_binds": True})), 
                           reindent=True, keyword_case='upper')


def test_queries_are_equal():
    expected_query = users.select().limit(10)
    assert format_query(expected_query) == format_query(select_first_users(10))

如果比较基于精确的字符串匹配,我认为最好确保格式一致,因此使用 sqlparse。

它本身只处理 int 和字符串,但可以扩展,请参阅文档了解更多信息https://docs.sqlalchemy.org/en/13/faq/sqlexpressions.html#faq-sql-expression-string

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM