gpt4 book ai didi

python - 与工厂男孩的一对多关系

转载 作者:行者123 更新时间:2023-12-04 02:45:08 28 4
gpt4 key购买 nike

我的 SQLAlchemy 模型中有一个多对一的关系。一份报告有许多样本(为简洁起见进行了简化):

class Sample(db.Model, CRUDMixin):
sample_id = Column(Integer, primary_key=True)
report_id = Column(Integer, ForeignKey('report.report_id', ondelete='CASCADE'), index=True, nullable=False)
report = relationship('Report', back_populates='samples')

class Report(db.Model, CRUDMixin):
report_id = Column(Integer, primary_key=True)
samples = relationship('Sample', back_populates='report')

现在在我的测试中,我希望能够生成 Sample实例,或 Report实例,并填写缺失的关系。

class ReportFactory(BaseFactory):
class Meta:
model = models.Report
report_id = Faker('pyint')
samples = RelatedFactoryList('tests.factories.SampleFactory', size=3)

class SampleFactory(BaseFactory):
class Meta:
model = models.Sample
sample_id = Faker('pyint')
report = SubFactory(ReportFactory)

当我去创建这些实例时,工厂陷入了无限循环:
RecursionError: maximum recursion depth exceeded in comparison

但是,如果我尝试使用 SelfAttribute s 停止无限循环,我最终得到一个没有任何样本的报告:

class ReportFactory(BaseFactory):
samples = RelatedFactoryList('tests.factories.SampleFactory', size=3, report_id=SelfAttribute('..report_id'))

class SampleFactory(BaseFactory):
report = SubFactory(ReportFactory, samples=[])
report = factories.ReportFactory()
l = len(report.samples) # 0

但是,如果我生成 SampleSampleFactory() ,它正确地有一个 Report目的。

我应该如何正确设计我的工厂 SampleFactory()将生成 Sample与相关 Report , 和 ReportFactory()将生成 Report与 2 个关联 Samples ,没有无限循环?

最佳答案

我的最终解决方案实际上比我想象的要简单得多:

class ReportFactory(BaseFactory):
class Meta:
model = models.Report

samples = RelatedFactoryList('tests.factories.SampleFactory', 'report', size=3)


class SampleFactory(BaseFactory):
class Meta:
model = models.Sample

report = SubFactory(ReportFactory, samples=[])

关键是使用 RelatedFactoryList 的第二个参数。 ,它必须对应于子 上的父链接, 在这种情况下 'report' .另外,我用了 SubFactory(ReportFactory, samples=[]) ,这确保如果我构建单个样本,不会在父节点上创建额外的样本。

通过此设置,我可以构建一个样本,该样本将具有 Report与之关联,并且该报告只有 1 个 child Sample .相反,我可以构造一个 Report将自动填充 3 个子样本。

我认为不需要生成实际的模型 ID,因为一旦模型实际插入数据库,SQLAlchemy 就会自动完成。但是,如果您想在不使用数据库的情况下这样做,我认为@Xelnor 的 report_id = factory.SelfAttribute('report.id') 的解决方案将工作。

我遇到的唯一 Unresolved 问题是覆盖报告中的样本列表(例如 ReportFactory(samples = [SampleFactory()]) ),但我已经打开了一个记录此错误的问题: https://github.com/FactoryBoy/factory_boy/issues/636

关于python - 与工厂男孩的一对多关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57505777/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com