繁体   English   中英

来自 factoryboy 的自引用属性错误 SQLAlchemy model

[英]Attribute error from factoryboy for self-referencing SQLAlchemy model

我意识到之前已经提出了一个类似的问题( https://github.com/FactoryBoy/factory_boy/issues/173 ),但我已经尝试了该票证中的所有建议,但在创建自引用字段时仍然遇到问题 SQLAlchemy model。

具体来说,当我尝试使用这种格式在测试中创建 ScaleFactory object 时(如票证中所建议):

new_scale = factories.ScaleFactory(code=test_code, description_student=test_description_student, parent_scale__parent_scale=None)

我收到以下错误:

  obj = None, name = 'id', default = <class 'factory.declarations._UNSPECIFIED'> . 

  def deepgetattr(obj, name, default=_UNSPECIFIED):
      """Try to retrieve the given attribute of an object, digging on '.'.

      This is an extended getattr, digging deeper if '.' is found.

      Args:
          obj (object): the object of which an attribute should be read
          name (str): the name of an attribute to look up.
          default (object): the default value to use if the attribute wasn't found

      Returns:
          the attribute pointed to by 'name', splitting on '.'.

      Raises:
          AttributeError: if obj has no 'name' attribute.
      """
      try:
          if '.' in name:
              attr, subname = name.split('.', 1)
              return deepgetattr(getattr(obj, attr), subname, default)
          else:
              return getattr(obj, name)
  E           AttributeError: 'NoneType' object has no attribute 'id'

我厂 model 是这样的:

class ScaleFactory(factory.alchemy.SQLAlchemyModelFactory):
    class Meta:
        model = models.Scale
        sqlalchemy_session = models.orm.session

    id = lazy_attribute(lambda o: fake.uuid4())
    ...
    parent_scale_id = factory.SelfAttribute("parent_scale.id")
    parent_scale = factory.SubFactory('application.factories.ScaleFactory')

我的 model 是这样的:

class Scale(orm.Model):
    __tablename__ = "scale"
    id = orm.Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
    ...
    parent_scale_id = orm.Column(UUID(as_uuid=True), orm.ForeignKey("scale.id"))
    parent_scale = orm.relationship("Scale", remote_side=[id])

我还尝试了有关该支持票的所有其他建议(@factory.post_generation 等),但都导致无限递归。 唯一不会产生无限递归的调用是我在此处给出的调用,但这会导致您看到的 AttributeError。 很可能我只是不明白我应该在这里传递什么而不是 None 作为 parent_scale__parent_scale。 我也尝试过创建一个 MagicMock obj 并将其作为 parent_scale 传递,但这会产生一个 AttributeError 试图找到__name__ 所以我完全被困住了。 非常感谢任何帮助。

我在工厂男孩==2.12.0

要回答我自己的问题,以防它对任何人有所帮助 - 一种防止无限递归和 AttributeError 的方法是按照原始答案中的建议传递 None 值( https://github.com/FactoryBoy /factory_boy/issues/173 )但还实现了一个post_generation挂钩来设置parent_scale_id

class ScaleFactory(factory.alchemy.SQLAlchemyModelFactory):
    class Meta:
        model = models.Scale
        sqlalchemy_session = models.orm.session

    id = lazy_attribute(lambda o: fake.uuid4())
    ...
    parent_scale = factory.SubFactory("application.factories.ScaleFactory")

    @factory.post_generation
    def parent_scale_id(self, create, _, **__):
        self.parent_scale_id = self.parent_scale.id if self.parent_scale else None

像这样称呼它:

new_scale = factories.ScaleFactory(code=test_code, description_student=test_description_student, parent_scale__parent_scale__parent_scale__parent_scale=None)                             

这将为您提供一个带有 3 个父秤的秤。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM