我有一个名为“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"))
提前感谢所有人! 丹尼尔
答案 0 :(得分: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
的文档中看到的,如果您确实需要在关联级别存储更多数据,那么它将是一个结构。