用于索引和查询ZODB的框架
项目描述
ObjectQuery
ObjectQuery受ZPL 2.1许可。
版权所有 © 2007-2009 gocept gmbh & co. kg。
ObjectQuery使您能够查询持久对象(例如ZODB中的对象)。这是通过一个类似于XPath的语言,即正则路径表达式(RPE)来完成的。ObjectQuery还包括索引结构以提高性能。
它使用 SimpleParse 来解析RPE查询。
请将错误报告给 gocept项目门户。
使用正则路径表达式查询对象
初始化
首先加载测试数据库。有关更多信息,请参阅objects.py中的内容。
>>> from gocept.objectquery.tests.objects import * >>> import ZODB.MappingStorage >>> import ZODB >>> from gocept.objectquery.collection import ObjectCollection >>> storage = ZODB.MappingStorage.MappingStorage() >>> db = ZODB.DB(storage) >>> conn = db.open() >>> dbroot = conn.root() >>> dbroot['_oq_collection'] = objects = ObjectCollection(conn) >>> import transaction >>> import gocept.objectquery.indexsupport >>> index_synch = gocept.objectquery.indexsupport.IndexSynchronizer() >>> transaction.manager.registerSynch(index_synch)>>> p_orwell = Person(name="George Orwell") >>> p_lotze = Person(name="Thomas Lotze") >>> p_goethe = Person(name="Johann Wolfgang von Goethe") >>> p_weitershausen = Person(name="Philipp von Weitershausen")>>> b_1984 = Book(author=p_orwell, ... title="1984", ... written=1990, ... isbn=3548234100) >>> b_plone = Book(author=p_lotze, ... title="Plone-Benutzerhandbuch", ... written=2008, ... isbn=3939471038) >>> b_faust = Book(author=p_goethe, ... title="Faust", ... written=1811, ... isbn=3406552501) >>> b_farm = Book(author=p_orwell, ... title="Farm der Tiere", ... written=2002, ... isbn=3257201184) >>> b_zope = Book(author=p_weitershausen, ... title="Web Component Development with Zope 3", ... written=2007, ... isbn=3540338071)>>> l_halle = Library(location="Halle", ... books=[b_1984, b_plone, b_farm, b_zope]) >>> l_berlin = Library(location="Berlin", ... books=[b_1984, b_plone, b_faust, b_farm, b_zope]) >>> l_chester = Library(location="Chester", ... books=[b_1984, b_faust, b_farm])>>> dbroot['librarydb'] = persistent.list.PersistentList() >>> dbroot['librarydb'].extend([l_halle, l_berlin, l_chester])>>> librarydb = dbroot['librarydb'] >>> transaction.commit()>>> from pprint import pprint
创建QueryProcessor并初始化ObjectCollection
您可以通过以下方式创建QueryProcessor
>>> from gocept.objectquery.pathexpressions import RPEQueryParser >>> from gocept.objectquery.processor import QueryProcessor >>> parser = RPEQueryParser() >>> query = QueryProcessor(parser, objects) >>> query <gocept.objectquery.processor.QueryProcessor object at 0x...>
一些示例用法
根连接
>>> r = query('/PersistentList/Library') >>> sorted(elem.location for elem in r) ['Berlin', 'Chester', 'Halle']
搜索所有名为“Faust”的书的作者
>>> r = query('/PersistentList/Library/Book[@title="Faust"]/Person') >>> sorted(elem.name for elem in r) ['Johann Wolfgang von Goethe']
搜索所有2000年后出版的书
>>> r = query('/PersistentList/Library/Book[@written>=2000]') >>> len(r) 3 >>> pprint(sorted(elem.title for elem in r)) ['Farm der Tiere', 'Plone-Benutzerhandbuch', 'Web Component Development with Zope 3']
搜索所有2000年后出版的书的作者
>>> r = query('/PersistentList/Library/Book[@written>=2000]/Person') >>> len(r) 3 >>> pprint(sorted(elem.name for elem in r)) ['George Orwell', 'Philipp von Weitershausen', 'Thomas Lotze']
搜索所有位于Halle且于2007年出版的Book
>>> r = query('/PersistentList/Library[@location="Halle"]/Book[@written==2007]') >>> sorted((elem.title, elem.isbn) for elem in r) [('Web Component Development with Zope 3', 3540338071L)]
正确处理通配符
>>> r = query('/PersistentList/Library/_/Person') >>> pprint(sorted(elem.name for elem in r)) ['George Orwell', 'Johann Wolfgang von Goethe', 'Philipp von Weitershausen', 'Thomas Lotze']
除了提供类名外,还可以提供带有完整模块的类
>>> r = query('/PersistentList/gocept.objectquery.tests.objects.Library') >>> pprint([library.location for library in r]) ['Halle', 'Berlin', 'Chester'] >>> query('/PersistentList/gocept.objectquery.tests.objects2.Library') []
关于优先级
>>> r = query('/PersistentList/Library[@location="Halle"]/Book/Person') >>> pprint(sorted(elem.name for elem in r)) ['George Orwell', 'Philipp von Weitershausen', 'Thomas Lotze']>>> r = query('(/PersistentList/Library[@location="Halle"]/Book)/Person') >>> pprint(sorted(elem.name for elem in r)) ['George Orwell', 'Philipp von Weitershausen', 'Thomas Lotze']>>> r = query('/PersistentList/Library[@location="Halle"]/(Book/Person)') >>> len(r) 0 >>> r = query('(/PersistentList/Library/Book[@title="Faust"])/(Book/Person)') >>> sorted(elem.name for elem in r) ['Johann Wolfgang von Goethe']
但请注意。如果您将查询从 ..”]/(Book.. 更改为 ..”](/Book..,您将得到一个位置在“Halle”的Library-Result。这是因为子查询(括号中的)没有返回结果
>>> r = query('/PersistentList/Library[@location="Halle"](/Book/Person)') >>> len(r) 1 >>> r[0].location 'Halle'
并集
>>> r = query('(/PersistentList/Library[@location="Halle"])|(Book/Person)') >>> len(r) 5 >>> pprint(sorted(elem for elem in r)) [<gocept.objectquery.tests.objects.Library object at 0x...>, <gocept.objectquery.tests.objects.Person object at 0x...>, <gocept.objectquery.tests.objects.Person object at 0x...>, <gocept.objectquery.tests.objects.Person object at 0x...>, <gocept.objectquery.tests.objects.Person object at 0x...>]>>> r = query('(/PersistentList/Library)|(Book[@written=1990])') >>> len(r) 4 >>> pprint(sorted(elem for elem in r)) [<gocept.objectquery.tests.objects.Book object at 0x...>, <gocept.objectquery.tests.objects.Library object at 0x...>, <gocept.objectquery.tests.objects.Library object at 0x...>, <gocept.objectquery.tests.objects.Library object at 0x...>]>>> transaction.commit()
kleene闭包
首先我们需要一个新的数据库
>>> doc1 = Document() >>> doc2 = Document() >>> doc3 = Document() >>> fol4 = Folder([doc2]) >>> fol3 = Folder([doc1]) >>> fol2 = Folder([fol3]) >>> fol1 = Folder([fol2]) >>> plo1 = Plone([fol1, fol4, doc3]) >>> root = Root([plo1])>>> dbroot['test'] = root >>> transaction.commit()
现在应该有一个Plone对象在根目录下
>>> r = query('/Root/Plone') >>> len(r) == 1 and r[0] == plo1 True>>> r = query('/Root/Plone/Folder/Document') >>> len(r) 1 >>> r[0] == doc2 True
获取所有位于任意数量的文件夹下的Document
>>> r = query('/Root/Plone/Folder*/Document') >>> r[0] != r[1] != r[2] and isinstance(r[0], Document) True>>> r = query('Plone/Folder*/Document') >>> r[0] != r[1] != r[2] and isinstance(r[0], Document) True>>> r = query('Folder*/Document') >>> r[0] != r[1] != r[2] and isinstance(r[0], Document) True
获取所有位于一个或零个文件夹下的Document
>>> r = query('/Root/Plone/Folder?/Document') >>> len(r) == 2 and (r[0] == doc2 or r[1] == doc2) and (r[0] == doc3 or r[1] == doc3) and r[0] != r[1] True>>> r = query('Folder?/Document') >>> len(r) == 3 and r[0] != r[1] != r[2] True
获取所有位于一个或多个文件夹下的文档
>>> r = query('/Root/Plone/Folder+/Document') >>> len(r) == 2 and (r[0] == doc1 or r[1] == doc1) and (r[0] == doc2 or r[1] == doc2) and r[0] != r[1] True>>> r = query('Folder+/Document') >>> len(r) == 2 and (r[0] == doc1 or r[1] == doc1) and (r[0] == doc2 or r[1] == doc2) and r[0] != r[1] True
您还可以查询绝对路径长度
>>> len(query('Plone/Document')) 1 >>> len(query('Plone/Folder/Document')) 1 >>> len(query('Plone/Folder/Folder/Document')) 0 >>> len(query('Plone/Folder/Folder/Folder/Document')) 1
此外,还可以查询位于2个或更多文件夹下的所有文档
>>> r = query('Plone/Folder+/Folder/Document') >>> len(r) == 1 and r[0] == doc1 True>>> r = query('Plone/Folder/Folder+/Document') >>> len(r) == 1 and r[0] == doc1 True
一个特殊案例是通配符与‘*’闭合的组合
>>> r = query('Plone/_*/Document') >>> len(r) == 3 True
变更
0.1b1 (2009-08-13)
通过添加SimpleParse egg来支持Windows
使用sw.objectinspection代替ObjectParser来检查对象的属性和子对象。这为检查自定义对象提供了更大的灵活性。
0.1b (2009-07-23)
小的API重构(#5780)
添加对查询给定模块中类别的支持(#5778)。
添加对查询对象基类的支持(#4880)。
0.1a2 (2009-06-17)
更好地处理非持久化对象。
0.1a1 (2009-06-05)
停止忽略可调用对象(例如Plone站点)进行索引,仅忽略一次方法。
如果在索引过程中添加的对象没有添加到ZODB(没有_p_oid属性),则不会中断。这些对象目前被忽略,不会添加到索引结构中。
添加rindex方法以递归地添加对象到集合中。
由于几个月来无法从pypi检索到,因此将SimpleParse作为第三方egg添加。
0.1pre (2009-02-04)
第一个alpha版本
0.1pre (2008-08-19)
基于毕业论文的工作的初始功能
项目详情
gocept.objectquery-0.1b1.tar.gz的散列
算法 | 散列摘要 | |
---|---|---|
SHA256 | c1b23e3119d251d35cf318bd4187b8d45a4b6269664b4c59bc353c384da13b89 |
|
MD5 | e9e7593b6e28c4e43784265507946c41 |
|
BLAKE2b-256 | 75c3f56a22f34675c1c620bd2d927aa6d232fbb230f6c7d94fb6f193af0bf7fe |