2014-01-08 101 views
0

我有一个名为“Subtests”的表和一个名为“TestSteps”的表(在使用SQLalchemy的sqlite数据库中),我想允许测试步骤在多个分测验。这需要在同一个“TestStep”表格列中存储多个对子测试ID的引用。这可能吗?本质上它是“TestSteps”表中外键列表的一个例子。这种关系如何建立?我在SQLAlchemy文档中看到了一些对外键列表的引用,但没有找到具体的例子。引用同一个表的一列中的多个外键

当前当我尝试添加对TestStep外键列(“subTestID”)的第二个引用时,它将覆盖原始条目。我想将多个条目存储为外键列表。

这里是如何的表已被初始化:

class SubTest(Base): 

    __tablename__ = "SubTests" 
    id = Column(Integer, primary_key=True) 
    testSteps = relationship("TestStep", backref = "subTest", order_by=TestStep.testStepNumber) 


class TestStep(Base): 

    __tablename__ = "TestSteps" 
    id = Column(Integer, primary_key = True) 
    subTestID = Column(Integer, ForeignKey("SubTests.id")) 

感谢所有提前! 丹尼尔

回答

1

这是不可能与您有的当前结构。您目前使用的机型为 One To Many型号为relationship

你所需要的就是一个Many To Many
你应该阅读链接到上述文件,但主要的一点是:你需要有一个关系表,将持有的关系对。下面的代码应该显示它根据你的模型:

teststep_subtest = Table('teststep_subtest', 
    Base.metadata, 
    Column('subtest_id', Integer, ForeignKey('SubTests.id'), primary_key=True), 
    Column('teststep_id', Integer, ForeignKey('TestSteps.id'), primary_key=True), 
    ) 

class TestStep(Base): 
    __tablename__ = "TestSteps" 
    id = Column(Integer, primary_key = True) 
    tag = Column(String) # @note: just for tests 
    #subTestID = Column(Integer, ForeignKey("SubTests.id")) # @note: removed 
    testStepNumber = Column(Integer) 

class SubTest(Base): 
    __tablename__ = "SubTests" 
    id = Column(Integer, primary_key=True) 
    tag = Column(String) # @note: just for tests 
    #testSteps = relationship("TestStep", backref = "subTest", order_by=TestStep.testStepNumber) 
    testSteps = relationship('TestStep', 
      secondary=teststep_subtest, 
      backref='subTests', 
      order_by=TestStep.testStepNumber, 
      ) 

下方的样本测试代码:

ts1 = TestStep(tag="start", testStepNumber=0) 
ts2 = TestStep(tag="do-something-cool") 
ts3 = TestStep(tag="do-something-groovy") 
ts4 = TestStep(tag="do-nothing") 
ts5 = TestStep(tag="finish", testStepNumber=9) 


st1 = SubTest(tag="sub-test-01", testSteps=[ts5, ts2, ts3, ts4, ts1]) 
st2 = SubTest(tag="sub-test-02", testSteps=[ts5, ts3, ts1]) 
st3 = SubTest(tag="sub-test-03-nosteps") 
session.add_all([ts1, ts2, ts3, ts4, ts5, st1, st2, st3]) 
session.commit() 
session.expunge_all() 

# query test 
print '-' * 80 
#engine.echo = False 
for _st in session.query(SubTest).all(): 
    print "SubTest:", _st.tag 
    for _ts in _st.testSteps: 
     print " ", _ts.testStepNumber, _ts.tag 

应该产生的输出是这样的:

SubTest: sub-test-01 
    None do-something-cool 
    None do-something-groovy 
    None do-nothing 
    0 start 
    9 finish 
SubTest: sub-test-02 
    None do-something-groovy 
    0 start 
    9 finish 
SubTest: sub-test-03-nosteps 

我觉得上面应该给你很好的介绍了多对多。不过,我怀疑它对你来说不够好,因为我猜testStepNumber可能需要每个TestStep都不相同。在这种情况下,你会这个字段移动到关系表,在此阶段你到另一种解决方案:

(可选)下一步:Association Object
正如您将从Association Object的文档,看它如果你确实需要在关联层面上存储更多的数据,那么结构就会是这样。

+0

谢谢!这正是我想到的。而且我确实看到了您建议的关联对象的需要。 – user2860797

相关问题