簡體   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