簡體   English   中英

RDFLib或rdflib-sqlalchemy:graph.remove函數無提示失敗

[英]RDFLib or rdflib-sqlalchemy: graph.remove function fails silently

我正在使用rdflib-sqlalchemy構建基於Django的語義應用程序來處理triplestore和數據庫邏輯之間的轉換。 我無法確定問題是使用rdflib-sqlalchemy還是使用RDFLib本身,但是當我嘗試從Django應用程序中刪除三元組時,對數據庫的三元組部分沒有影響,並且圖形返回相同的刪除嘗試之前和之后的三元組數。 如果我從Python控制台嘗試相同的過程(相同的VirtualEnv,相同的基礎數據,但不同的數據庫),graph.remove()函數按預期工作。 我沒有看到任何與此類似的東西,但我可能會遺漏一些東西。

因此,例如,以下內容可用作刪除所有三元組的方法,其中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交互式控制台中使用相同的方法:

>>> 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

但是當我從一個信號中調用它時,沒有任何效果。 在我發布Signal代碼之前,讓我簡要介紹一下我管理三元組的方法,它實際上是復合鍵(Django缺乏支持的東西)。 我所做的是創建一個Django管理的模型來列出資源(例如,任何可以是貓頭鷹:NamedIndividual,所以既不是謂詞也不是文字)和五個非托管模型,它們映射到rdflib-sqlalchemy的數據庫表(包括id(pk)字段,自4ee1791起)。 通過管理命令填充存儲使用rdflib-sqlalchemy將數據放入正確的非托管表中,之后我遍歷TypeStatements並獲取唯一的資源集來填充托管的Resource表。 這反過來驅動管理界面的一部分,以便可以以統一的方式管理資源,作為缺乏復合鍵支持的解決方法。

現在,我的管理界面中的所有內容都可用於列表。 所以我想添加一個模擬級聯刪除的刪除函數,這樣如果刪除一個Resource對象,它會刪除所有三元組作為主題,並將所有三元組作為對象刪除。 我對如何插入附加到對象刪除功能的附加功能的研究使我得到了信號。 下面是我為Resource對象的pre_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

資源模型對象按預期刪除,但三元組仍保留在商店中。

所以問題是我如何讓它實際工作? 我在信號中做錯了嗎?

我認為這不重要,但我使用sqlite作為我的數據庫。 沒有錯誤消息,我沒有想到數據庫在Django wsgi運行時被鎖定。 這似乎不是在Django交互式控制台下發生的,這就是為什么函數在那里工作沒有問題。

無論如何,我切換到PostgreSQL,邏輯現在作為excetd工作。 我想我的設置依賴於與數據庫的多個同時連接,只要rdflib-sqlalchemy只是要讀取商店就可以了。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM