RDFLib或rdflibsqlalchemy:图形删除函数无声地失败

2024-05-29 07:50:58 发布

您现在位置:Python中文网/ 问答频道 /正文

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

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

>>> 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交互式控制台中使用相同的方法:

^{2}$

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

现在,我的管理界面中的所有内容都是为了列表目的而工作的。所以我想添加一个delete函数来模拟级联删除,这样如果删除一个资源对象,它会删除所有以该资源为主题的三元组和以该资源为对象的所有三元组。我对如何插入附加在对象删除函数上的附加函数的研究使我想到了信号。下面是我为预删除资源对象创建的信号。我添加了控制台日志,只是为了帮助调试;其输出也如下所示。在

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__())

以及日志输出:

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

资源模型对象按预期被删除,但三元组仍保留在存储区中。在

所以问题是我怎样才能让它真正起作用?我的信号有问题吗?在


Tags: tofromhttpsimportnoneurllen资源
1条回答
网友
1楼 · 发布于 2024-05-29 07:50:58

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

不管怎样,我换成了PostgreSQL,它的逻辑现在像expeced一样工作。我想我的设置依赖于对数据库的多个同时连接,只要rdflibsqlalchemy要读取存储,这就很好了。在

相关问题 更多 >

    热门问题