[英]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.