2013-02-27 33 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