我可以使用glob模式查询数据库吗?

时间:2016-11-14 20:21:24

标签: python regex django postgresql glob

我在尝试使用glob模式查询数据库时遇到了麻烦。

我认为也许glob可以被翻译成正则表达式,我知道I can query db using regex。我自己打算进行翻译,但是我发现python有fnmatch就可以了,显式函数translate

  

fnmatch.translate(图案)

     

返回转换为正则表达式的shell样式模式,以便与re.match()一起使用。

所以我尝试将两者结合起来,但......

>>> from vte.models import VTE
>>> import fnmatch
>>> regex = fnmatch.translate('19*')
>>> regex
'19.*\\Z(?ms)'
>>> VTE.objects.filter(ipaddr__regex=regex)
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/var/www/vtfx/env/local/lib/python2.7/site-packages/django/db/models/query.py", line 234, in __repr__
    data = list(self[:REPR_OUTPUT_SIZE + 1])
  File "/var/www/vtfx/env/local/lib/python2.7/site-packages/django/db/models/query.py", line 258, in __iter__
    self._fetch_all()
  File "/var/www/vtfx/env/local/lib/python2.7/site-packages/django/db/models/query.py", line 1074, in _fetch_all
    self._result_cache = list(self.iterator())
  File "/var/www/vtfx/env/local/lib/python2.7/site-packages/django/db/models/query.py", line 52, in __iter__
    results = compiler.execute_sql()
  File "/var/www/vtfx/env/local/lib/python2.7/site-packages/django/db/models/sql/compiler.py", line 848, in execute_sql
    cursor.execute(sql, params)
  File "/var/www/vtfx/env/local/lib/python2.7/site-packages/django/db/backends/utils.py", line 79, in execute
    return super(CursorDebugWrapper, self).execute(sql, params)
  File "/var/www/vtfx/env/local/lib/python2.7/site-packages/django/db/backends/utils.py", line 64, in execute
    return self.cursor.execute(sql, params)
  File "/var/www/vtfx/env/local/lib/python2.7/site-packages/django/db/utils.py", line 95, in __exit__
    six.reraise(dj_exc_type, dj_exc_value, traceback)
  File "/var/www/vtfx/env/local/lib/python2.7/site-packages/django/db/backends/utils.py", line 64, in execute
    return self.cursor.execute(sql, params)
DataError: invalid regular expression: quantifier operand invalid

我不明白错误信息。

根据django的文档,这应该在postgresql中翻译(db我正在使用,顺便说一下)到这样的东西

SELECT ... WHERE ipaddr ~ '19.*\\Z(?ms)';

Here it is the ~ operator documentation.

所以我尝试更改translate()返回的regexp,并且在删除? char时不会抛出错误。

然后我想,如果没有最后一部分\\Z(?ms),也许glob-gt;正则表达式翻译工作正常,但我不确定,我可能会遗漏一些东西。

回顾:

  • 这会引发错误19.*\\Z(?ms)
  • 这不会抛出错误19.*\\Z(ms)
  • 我认为这可以按预期工作19.*

所以新代码就像这样

>>> VTE.objects.filter(ipaddr__regex=regex.replace('\\Z(?ms)', ''))
[<VTE: 192.168.56.100>]

.replace('\\Z(?ms)', '')时我错过了什么?为什么这有必要?这是一个很好的解决方案吗?

1 个答案:

答案 0 :(得分:3)

根据对我的问题的评论,我最终做了以下

import fnmatch
globex = ......
regex = '^{}'.format(fnmatch.translate(globex).replace('\\Z(?ms)', '$'))
VTE.objects.filter(ipaddr__regex=regex)

这似乎与postgresql和javascript正则表达式实现兼容。