我可以使用 glob 模式查询数据库吗?
Can I query the DB using a glob pattern?
我在尝试使用 glob 模式查询数据库时遇到问题。
我想也许 glob 可以翻译成正则表达式,我知道 I can query db using regex. I was going to to that translation myself, but I found that python has fnmatch 可以做到这一点,明确的函数 translate
fnmatch.translate(pattern)
Return the shell-style pattern converted to a regular expression for using with 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(顺便说一句,我正在使用的数据库)中翻译成这样的东西
SELECT ... WHERE ipaddr ~ '19.*\Z(?ms)';
Here it is the ~
operator documentation.
所以我尝试稍微更改 translate()
返回的正则表达式,并且在删除 ?
字符时不会抛出错误。
然后我想,如果没有这最后一部分,glob->regex 翻译可能工作正常 \Z(?ms)
但我不确定,我可能遗漏了一些东西。
回顾:
- 这会引发错误
19.*\Z(?ms)
- 这不会引发错误
19.*\Z(ms)
- 我认为这符合预期
19.*
所以新代码应该是这样的
>>> VTE.objects.filter(ipaddr__regex=regex.replace('\Z(?ms)', ''))
[<VTE: 192.168.56.100>]
我在做 .replace('\Z(?ms)', '')
时错过了什么?为什么这是必要的?这是一个好的解决方案吗?
根据对我的问题的评论,我最终做了以下事情
import fnmatch
globex = ......
regex = '^{}'.format(fnmatch.translate(globex).replace('\Z(?ms)', '$'))
VTE.objects.filter(ipaddr__regex=regex)
这似乎与 postgresql 和 javascript 正则表达式实现兼容。
我在尝试使用 glob 模式查询数据库时遇到问题。
我想也许 glob 可以翻译成正则表达式,我知道 I can query db using regex. I was going to to that translation myself, but I found that python has fnmatch 可以做到这一点,明确的函数 translate
fnmatch.translate(pattern)
Return the shell-style pattern converted to a regular expression for using with 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(顺便说一句,我正在使用的数据库)中翻译成这样的东西
SELECT ... WHERE ipaddr ~ '19.*\Z(?ms)';
Here it is the ~
operator documentation.
所以我尝试稍微更改 translate()
返回的正则表达式,并且在删除 ?
字符时不会抛出错误。
然后我想,如果没有这最后一部分,glob->regex 翻译可能工作正常 \Z(?ms)
但我不确定,我可能遗漏了一些东西。
回顾:
- 这会引发错误
19.*\Z(?ms)
- 这不会引发错误
19.*\Z(ms)
- 我认为这符合预期
19.*
所以新代码应该是这样的
>>> VTE.objects.filter(ipaddr__regex=regex.replace('\Z(?ms)', ''))
[<VTE: 192.168.56.100>]
我在做 .replace('\Z(?ms)', '')
时错过了什么?为什么这是必要的?这是一个好的解决方案吗?
根据对我的问题的评论,我最终做了以下事情
import fnmatch
globex = ......
regex = '^{}'.format(fnmatch.translate(globex).replace('\Z(?ms)', '$'))
VTE.objects.filter(ipaddr__regex=regex)
这似乎与 postgresql 和 javascript 正则表达式实现兼容。