我有一个字符串,需要查找所有具有匹配前缀的记录:
path = '/abc/123/456'
session.query(Site).filter(path.startswith(Site.path_prefix))
以下记录将在path_prefix等于以下内容时匹配:
/abc
/ab
/abc/123
但不包括:
/asd
/abc/123/456/789
/kjk
使用SqlAlchemy,而不需要切换到Python,这是否可能?
我有一个字符串,需要查找所有具有匹配前缀的记录:
path = '/abc/123/456'
session.query(Site).filter(path.startswith(Site.path_prefix))
/abc
/ab
/abc/123
但不包括:
/asd
/abc/123/456/789
/kjk
使用SqlAlchemy,而不需要切换到Python,这是否可能?
如果你将path
变量包装在一个bindparam()
对象中,那么你可以像对待任何列一样对待它,包括使用.contains()
和.startswith()
运算符:
from sqlalchemy.sql.expression import bindparam
session.query(Site).filter(bindparam('path', path).contains(Site.path_prefix))
SQLAlchemy将.contains()
翻译为:
? LIKE CONCAT('%', Site.path_prefix, '%')
关于 MySQL 或者
? LIKE '%' || Site.path_prefix || '%'
在其他数据库上也可以进行测试。
如果您想要测试 .startswith()
操作,那也可以:
from sqlalchemy.sql.expression import bindparam
session.query(Site).filter(bindparam('path', path).startswith(Site.path_prefix))
startswith (path,Site.path_prefix)
(将 path_prefix,path 作为参数)难道不正是我们陷入的陷阱吗? - Jon Clementsstartswith()
,但仅适用于列,因为这是反向的,所以我们需要自己构建LIKE
。 - Martijn Pietersfunctions.concat()
是过度的。使用 +
字符串连接就足够了,它会正确地转换为不同的数据库。 - Martijn Pietersbindparam()
,因此 SQLAlchemy 的 .startswith()
和 .contains()
运算符也可以使用。 - Martijn Pieters
Site.path_prefix in path
吗?此外,在纯 Python 语义中,这将匹配像23/4
和空字符串一样的字符串,这是你想要的吗? - kennytm