首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >RDFLib或rdflib-sqlalchemy: graph.remove函数以静默方式失败

RDFLib或rdflib-sqlalchemy: graph.remove函数以静默方式失败
EN

Stack Overflow用户
提问于 2016-04-12 03:19:47
回答 1查看 361关注 0票数 1

我正在构建一个基于Django的语义应用程序,使用rdflib-sqlalchemy来处理triplestore和数据库逻辑之间的转换。我真的不知道是rdflib-sqlalchemy的问题还是RDFLib本身的问题,但是当我尝试从Django应用程序中删除三元组时,对数据库的三元组部分没有影响,并且图形在删除尝试前后返回了相同的三元组计数。如果我从Python控制台尝试相同的过程(相同的VirtualEnv,相同的基本数据,但不同的数据库),graph.remove()函数将按预期工作。我没有看到任何东西,甚至与此非常相似,但我可能遗漏了一些东西。

因此,例如,以下代码可以作为删除所有以https://url.to/scheme/MADAGASCAR为主题的三元组的方法:

代码语言:javascript
复制
>>> g
<Graph identifier=foo (<class 'rdflib.graph.ConjunctiveGraph'>)>
>>> g.store
<Partitioned SQL N3 Store>
>>> len(list(g.triples(('https://url.to/scheme/MADAGASCAR',None,None))))
11
>>> g.remove(('https://url.to/scheme/MADAGASCAR',None,None))
>>> len(list(g.triples(('https://url.to/scheme/MADAGASCAR',None,None))))
0

同样,我可以在我的Django交互控制台中使用相同的方法:

代码语言:javascript
复制
>>> from django.conf import settings
>>> from rdflib_sqlalchemy.SQLAlchemy import SQLAlchemy
>>> from semantic.models import Namespace, AssertionStatement, LiteralStatement, QuotedStatement, TypeStatement, Resource
>>> g = settings.GRAPH
>>> len(list(g.triples(('https://url.to/scheme/MADAGASCAR',None,None))))
11
>>> g.remove(('https://url.to/scheme/MADAGASCAR',None,None))
>>> len(list(g.triples(('https://url.to/scheme/MADAGASCAR',None,None))))
0

但是,当我从一个信号中调用它时,没有任何效果。在我发布信号代码之前,让我简要描述一下我管理三元组的方法,三元组是有效的复合键( Django缺乏对它的支持)。我所做的就是创建一个Django托管模型来列出资源(例如,任何可以是owl:NamedIndividual的模型,所以既不是谓词也不是文字)和五个映射到rdflib-sqlalchemy的数据库表(从4ee1791开始包括id (pk)字段)的非托管模型。通过管理命令填充存储区将使用rdflib-sqlalchemy将数据放入正确的非托管表中,之后我将遍历TypeStatements并获取唯一的资源集来填充托管资源表。这反过来又驱动了管理界面的一部分,因此可以以统一的方式管理资源,作为缺乏复合键支持的变通办法。

现在,我的管理界面中的所有内容都可以用于列表。所以我想添加一个delete函数来模拟级联删除,这样如果您删除一个Resource对象,它将删除所有以该Resource为主体的三元组,以及以该Resources为宾语的所有三元组。我对如何插入附加到对象删除函数的附加函数的研究将我引向了信号。下面是我为资源对象的pre_delete创建的信号。我添加了控制台日志记录,只是为了帮助调试;它的输出也如下所示。

代码语言:javascript
复制
from django.db.models.signals import pre_save, pre_delete, post_save, post_delete
from django.dispatch import receiver
from django.conf import settings
from semantic.models import Namespace, AssertionStatement, LiteralStatement, QuotedStatement, TypeStatement, Resource
from rdflib_sqlalchemy.SQLAlchemy import SQLAlchemy
from rdflib import ConjunctiveGraph, URIRef

graph = settings.GRAPH

# When something is deleted from the Resource table, we want to delete all of its associated inbound and outbound triples
@receiver(pre_delete, sender=Resource)
def model_pre_change(sender, **kwargs):
  print("Before delete, the graph has %s triples" % len(graph))
  print("There are %s " % len(list(graph.triples((kwargs['instance'].__str__(),None,None)))) + "triples associated with %s " % kwargs['instance'].__str__())

  # Not sure why graph.remove(triple_or_quad) doesn't seem to work...
  graph.remove((kwargs['instance'].__str__(),None,None))
  graph.remove((None,None,kwargs['instance'].__str__()))


@receiver(post_delete, sender=Resource)
def model_post_change(sender, **kwargs):
  # This is for debugging only.
  print("After delete, the graph has %s triples" % len(graph))
  print("There are %s " % len(list(graph.triples((kwargs['instance'].__str__(),None,None)))) + "triples associated with %s " % kwargs['instance'].__str__())

和日志输出:

代码语言:javascript
复制
Before delete, the graph has 2178 triples
There are 11 triples associated with https://url.to/scheme/MADAGASCAR
After delete, the graph has 2178 triples
There are 11 triples associated with https://url.to/scheme/MADAGASCAR

Resource模型对象如预期的那样被删除,但三元组仍保留在存储中。

所以问题是,我如何让它真正起作用?我的信号是不是做错了什么?

EN

回答 1

Stack Overflow用户

发布于 2016-04-13 03:37:35

我认为这无关紧要,但我使用的是sqlite作为我的数据库。在没有错误消息的情况下,我没有想到数据库在Django wsgi运行时被锁定。这似乎不会发生在Django交互控制台下,这就是为什么函数在那里没有问题的原因。

无论如何,我切换到了PostgreSQL,逻辑现在可以正常工作了。我猜我的设置依赖于到数据库的多个同步连接,只要rdflib-sqlalchemy只是要读取存储就可以了。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36557413

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档