2016-04-11 15 views
1

Triplettore ve veritabanı mantığı arasındaki çeviri işlemek için rdflib-sqlalchemy kullanarak Django tabanlı bir semantik uygulama oluşturma aşamasındayım. Sorunun rdflib-sqlalchemy veya RDFLib ile olup olmadığını gerçekten söyleyemem, ancak Django uygulamasının içinden üçlüleri kaldırmaya çalıştığımda, veritabanının üçlü kısmı üzerinde hiçbir etkisi yoktur ve grafik aynıdır. silme girişimi öncesi ve sonrası üçlü sayısı. Aynı prosedürü Python konsolundan (aynı VirtualEnv, aynı temel veri, ancak farklı veritabanı) denediğimde, graph.remove() işlevi beklendiği gibi çalışır. SO üzerinde hiçbir şey göremiyorum ki bu bile buna çok benziyor, ama bir şeyleri kaçırıyor olabilirim.RDFLib veya rdflib-sqlalchemy: graph.remove işlevi başarısız bir şekilde başarısız oluyor

Dolayısıyla, örneğin, konu olarak https://url.to/scheme/MADAGASCAR ile tüm üçe silme aracı olarak aşağıdaki çalışır:

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

Benzer şekilde, benim Django interaktif konsoldan içinden aynı yöntemleri kullanabilirsiniz:

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

Fakat bunu bir Sinyal içinden çağırdığımda, bir etkisi yoktur. Sinyal kodunu yayınlamadan önce, kısaca bileşik anahtarlar olan (Django'nun desteklemediği bir şey) üçlü yönetme yaklaşımımı kısaca anlatayım. Yaptığım şey, kaynakları listelemek için tek bir Django tarafından yönetilen bir model oluşturdu (örneğin, bir baykuş olabilecek her şey: Adlandırılan Bireysel, bu nedenle ne yüklemi ne de gerçekleri) ve rdflib-sqlalchemy'nin veritabanı tablolarını eşleyen beş yönetilmeyen model. ID (pk) alanları 4ee1791). Depoyu bir yönetim komutuyla doldurmak, verileri doğru yönetilmeyen tablolara yerleştirmek için rdflib-sqlalchemy işlevini kullanır. Bundan sonra, TypeStatements aracılığıyla yineliyorum ve yönetilen Kaynak tablosunu doldurmak için benzersiz kaynak kümesini elde ediyorum. Bu da yönetici arayüzünün bir kısmını yönlendirir, böylelikle Bileşik anahtar desteğinin yokluğu için bir çözüm olarak Kaynakların birleşik bir şekilde yönetilmesi mümkün olur.

Artık, yönetici arayüzümdeki her şey listeleme amaçlı çalışıyor. Bu yüzden, bir Resource nesnesini silerseniz, o Kaynak ile konuyla ilgili tüm üçlüyü ve o Kaynaklarla nesne olarak tüm üçlüleri silecek şekilde bir kaskatı taklit edecek bir silme fonksiyonu eklemek istedim. Nesne silme fonksiyonuna eklenen ek fonksiyonlarla nasıl etkileşime gireceğime dair araştırmam beni Sinyallere yönlendirdi. Aşağıda bir Kaynak nesnenin pre_delete'si için oluşturduğum Sinyal. Sadece hata ayıklamaya yardımcı olmak için konsol günlüğü ekledim; Bunun çıktısı da takip eder.

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

Ve günlük çıkışı:

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 

beklendiği gibi kaynak modeli nesne silindiğinde, ancak üç katına deposunda kalır.

Soru şu ki, gerçekten işe yaramasını nasıl sağlayabilirim? Sinyallerimde yanlış bir şey mi yapıyorum?

cevap

0

Önemli olduğunu düşünmedim, ancak veritabanım için sqlite kullanıyordum. Hata mesajları olmadan, Django wsgi çalışırken veritabanı kilitlenir bana gelmedi. Bu, Django interaktif konsolu altında görünmüyor, bu yüzden buradaki işlev herhangi bir sorun olmadan çalıştı.

Her neyse PostgreSQL'e geçtim ve mantık şimdiki gibi çalışıyor. Kurulumumun veritabanına birden çok eşzamanlı bağlantıya bağlı olduğunu sanırım, ki bu da rdflib-sqlalchemy'nin sadece mağazayı okuyacağı kadar iyi.

İlgili konular