[Python] django e strutture dati permanenti

Riccardo Lemmi riccardo a reflab.com
Sab 13 Ott 2012 09:26:05 CEST


Riccardo Lemmi wrote:

> Balan Victor wrote:
> 
>> idee? :)
>> 
>> 
>> Il giorno 10 ottobre 2012 14:01, Balan Victor
>> <balan.victor0 a gmail.com> ha scritto:
>> 
>>> quello che devo fare č questo:
>>> in fase di inizializzazione devo caricare in memoria un
>>> grafo(networkx) di dimensioni consistenti: 60.000 nodi e pių di
>>> 100.000 connessioni. PER ADESSO dovrebbe essere in sola lettura e se
>>> devo fare delle modifiche posso permettermi di stoppare tutto, fare
>>> le modifiche e rilanciare l'applicazione.
>>> Poi in base alle richieste che vengono effettuate devo andare a
>>> leggere le informazioni che mi servono dal grafo, elaborarle e
>>> restituirle all'utente.
>>> ...
> 
> Non sarebbe meglio fare il pickle della struttura dati creata in
> memoria da networkx invece di ricreare il grafo ogni volta dal DB?
> 
> Ovviamente perchč sia fattibile bisogna controllare che gli oggetti di
> NetworkX siano effettivamente serializzabili, inoltre tenere allineati
> il DB e il grafo richiede sicuramente del codice specifico per evitare
> di buttare via tutto e ricreare da 0 ogni volta che cambia qualcosa.
> 
> Potrei anche arrivare a suggerire di provare a derivare (o patchare)
> le classi di NetworxX da Persistent dello ZODB per semplificare la
> serializzazione ed eliminare il DB relazionale...

Una prova fatta velocemente, ma sembra funzionare.

# store a networkx graph in a ZODB
# depends on
#   networkx
#   matplotlib
#   ZODB3
import sys

import networkx as nx
import matplotlib.pyplot as plt

from persistent import Persistent
from persistent.list import PersistentList
from persistent.dict import PersistentDict

from ZODB import FileStorage, DB
import transaction

#
root = None
storage = None
db = None
connection = None

def init_db():
    global root, storage, db, connection
    if root is None:
        storage = FileStorage.FileStorage('./g1.fs')
        db = DB(storage)
        connection = db.open()
        root = connection.root()

#
class PersistentGraph(Persistent, nx.Graph):

    def __init__(self, data=None, **attr):
        nx.Graph.__init__(self, data=None, **attr)
        self.graph = PersistentDict()   # dictionary for graph attributes
        self.node = PersistentDict()    # empty node dict (created before convert)
        self.adj = PersistentDict()     # empty adjacency dict

class Person(Persistent):

    def __init__(self, name):
        self.name = name

    def __repr__(self):
        return "<Person: %s>"%(self.name)

#
if __name__ == '__main__':
    init_db()

    if "G" not in root.keys():
        print "Adding some Person(s)"

        G = root["G"] = PersistentGraph()
        f = Person("Father")
        m = Person("Mother")
        c = Person("Child")

        G.add_edge(f, c)
        G.add_edge(m,c)

        transaction.commit()
    else:
        G = root["G"]

    if 'addWN' in sys.argv:
        print "Adding wife and son of Child"

        # these are not permanents until commit
        w = Person("Wife")
        n = Person("Nephew")
        c = [p for p in G.nodes() if p.name=="Child"][0]  # can be done better
        G.add_edge(n, w)
        G.add_edge(n, c)
        transaction.commit()

    if 'rmW' in sys.argv:
        res = [p for p in G.nodes() if p.name=="Wife"][0]
        if len(res)>0:
            print "Removing Wife"
            G.remove_node(res[0])
            transaction.commit()

    print "Showing"

    for n in G:
      print n

    nx.draw(G)
    plt.show()


-- 
                                       Riccardo Lemmi



Maggiori informazioni sulla lista Python