2013-02-27 80 views
0

我正在設計一個圖數據庫結構。一個節點可以是一個人,一個部門等。這就是爲什麼我添加了nodeType。節點之間的關係也可以有多種類型。 從下面的代碼中將r1和r2插入到數據庫中。當我讀取數據庫時,我看到null null null。這是爲什麼 ? 我期望看到,涉及到the.id字段(例如n1.id,rt1.id,n2.id)sqlalchemy圖數據庫數據操作

from sqlalchemy import MetaData, Table, Column, Integer, ForeignKey, \ 
    create_engine, String 
from sqlalchemy.orm import mapper, relationship, sessionmaker 
from sqlalchemy.ext.declarative import declarative_base 

engine = create_engine('sqlite:///dir_graph.sqlite', echo=True) 

Base = declarative_base() 
Session = sessionmaker(bind=engine) 
session = Session() 

class NodeType(Base): 
    __tablename__ = 'nodetype' 
    id  = Column(Integer, primary_key=True) 
    name = Column(String(20), unique=True) 
    nodes = relationship('Node', backref='nodetype') 

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

    def __repr__(self): 
     return "Nodetype: %s" % (self.name) 


class Node(Base): 
    __tablename__ = 'node' 

    id = Column(Integer, primary_key=True) 
    name = Column(String(20), unique=True) 
    type_id = Column(Integer, 
         ForeignKey('nodetype.id')) 

    def __init__(self, _name, _type_id): 
     self.name = _name 
     self.type_id = _type_id 

class Relation(Base): 
    __tablename__ = 'relation' 

    id  = Column(Integer, primary_key=True) 
    name = Column(String(20), unique=True) 
    type_id = Column(Integer, 
         ForeignKey('relationtype.id')) 

    from_id = Column(Integer, 
         ForeignKey('node.id')) 

    to_id = Column(Integer, 
         ForeignKey('node.id')) 


    def __init__(self, _fromNode, _type_id, _toNode): 
      self.from_id = _fromNode 
      self.type_id = _type_id 
      self.to_id = _toNode 

class RelationType(Base): 
    __tablename__ = 'relationtype' 

    id    = Column(Integer, primary_key=True) 
    name   = Column(String(20), unique=True) 
    description = Column(String(30), unique=True) 

    relations  = relationship('Relation', backref='relationtype') 

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

    def description(self, _description): 
     self.description = _description 
Base.metadata.create_all(engine) 

nt1 = NodeType('nt1') 
nt2 = NodeType('nt2') 

n1 = Node('n1type1', 1) 
n2 = Node('n2type1', 1) 
n3 = Node('n3type1', 1) 
n4 = Node('n4type2', 2) 
n5 = Node('n5type2', 2) 

rt1 = RelationType('rt1') 
rt2 = RelationType('rt2') 
rt3 = RelationType('rt3') 

r1 = Relation(n1.id,rt1.id,n2.id) 
r2 = Relation(n3.id,rt2.id,n5.id) 

session.add_all([nt1,nt2,n1,n2,n3,n4,n5,rt1,rt2,rt3,r1,r2]) 
session.commit() 

上改進代碼的其他評論也讚賞值。

+0

您必須指定「讀取數據庫」的含義。你試圖運行的查詢是什麼,並返回意外的NULL? – benselme 2013-02-27 16:57:04

+0

運行代碼後,我使用SQLiteStudio讀取數據庫。在我看到的表格關係中:id:1 name:null type:id:null from_id:null to_id:null同樣爲id:2 – ArtDijk 2013-02-27 17:11:31

回答

2

您的代碼存在的問題是您嘗試在將節點插入數據庫之前使用Node.id屬性。在您撥打session.flush()session.commit()之前,新創建的對象沒有標識,因爲它是生成標識的數據庫引擎。

這樣算下來,這將是定義Relation對象和Node對象之間的關係,並在指定的Relation.__init__對象,而不是將ID分配的SQLAlchemy的方式。就像這樣:

from sqlalchemy import MetaData, Table, Column, Integer, ForeignKey, \ 
    create_engine, String 
from sqlalchemy.orm import mapper, relationship, sessionmaker 
from sqlalchemy.ext.declarative import declarative_base 

engine = create_engine('sqlite:///dir_graph.sqlite', echo=True) 

Base = declarative_base() 
Session = sessionmaker(bind=engine) 
session = Session() 


class NodeType(Base): 
    __tablename__ = 'nodetype' 
    id = Column(Integer, primary_key=True) 
    name = Column(String(20), unique=True) 
    nodes = relationship('Node', backref='nodetype') 

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

    def __repr__(self): 
     return "Nodetype: %s" % self.name 


class Node(Base): 
    __tablename__ = 'node' 

    id = Column(Integer, primary_key=True) 
    name = Column(String(20), unique=True) 
    type_id = Column(Integer, 
        ForeignKey('nodetype.id')) 


    def __init__(self, _name, _type_id): 
     self.name = _name 
     self.type_id = _type_id 


class Relation(Base): 
    __tablename__ = 'relation' 

    id = Column(Integer, primary_key=True) 
    name = Column(String(20), unique=True) 
    type_id = Column(Integer, 
        ForeignKey('relationtype.id')) 

    from_id = Column(Integer, 
        ForeignKey('node.id')) 

    to_id = Column(Integer, 
        ForeignKey('node.id')) 

    from_node = relationship(Node, primaryjoin=Node.id == from_id) 
    to_node = relationship(Node, primaryjoin=Node.id == to_id) 

    def __init__(self, _fromNode, _type_id, _toNode): 
     self.from_node = _fromNode 
     self.type_id = _type_id 
     self.to_node = _toNode 


class RelationType(Base): 
    __tablename__ = 'relationtype' 

    id = Column(Integer, primary_key=True) 
    name = Column(String(20), unique=True) 
    description = Column(String(30), unique=True) 

    relations = relationship('Relation', backref='relationtype') 

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

    def description(self, _description): 
     self.description = _description 


Base.metadata.create_all(engine) 

nt1 = NodeType('nt1') 
nt2 = NodeType('nt2') 

n1 = Node('n1type1', 1) 
n2 = Node('n2type1', 1) 
n3 = Node('n3type1', 1) 
n4 = Node('n4type2', 2) 
n5 = Node('n5type2', 2) 

rt1 = RelationType('rt1') 
rt2 = RelationType('rt2') 
rt3 = RelationType('rt3') 

r1 = Relation(n1, rt1.id, n2) 
r2 = Relation(n3, rt2.id, n5) 

session.add_all([nt1, nt2, n1, n2, n3, n4, n5, rt1, rt2, rt3, r1, r2]) 
session.commit() 
+0

謝謝,現在工作正常。當代碼運行後我與解釋器交互時,出現線程錯誤。例如r3 =關係(n4,rt2.id,n5)導致線程錯誤的原因是什麼? (對不起,我是一個newby)謝謝 – ArtDijk 2013-02-27 18:29:19