使用factory_boy工厂避免重复项

2024-10-01 09:24:25 发布

您现在位置:Python中文网/ 问答频道 /正文

我使用factory_boy来创建测试夹具。我有两个简单的工厂,由SQLAlchemy模型支持(简化如下)。在

我希望能够多次调用AddressFactory.create(),如果它不存在,让它创建一个Country,否则我希望它重用现有记录。在

class CountryFactory(factory.Factory):
    FACTORY_FOR = Country

    cc = "US"
    name = "United States"


class AddressFactory(factory.Factory):
    FACTORY_FOR = Address

    name = "Joe User"
    city = "Seven Mile Beach"
    country = factory.SubFactory(CountryFactory, cc="KY", name="Cayman Islands")

我的问题是:我如何建立这些工厂,使工厂男孩不会在每次创建地址时都试图创建一个新的国家?


Tags: name模型forsqlalchemyfactory工厂country夹具
3条回答

虽然您对基于SQLAlchemy的工厂没有get_or_create函数是正确的,但是如果您想用作外键的对象已经存在,您可以迭代它们:

http://factoryboy.readthedocs.org/en/latest/recipes.html#choosing-from-a-populated-table

因此,可以想象的是,您可以通过使用lazy属性在您的工厂中构建一个解决方案,该属性首先检查数据库中是否存在该对象,如果确实存在,它将使用此方法迭代这些对象,但如果对象不存在,它将首先调用SubFactory来创建对象。在

在最新的factory boy==2.3.1中,您可以添加factory_DJANGO_GET_或_CREATE

class CountryFactory(factory.django.DjangoModelFactory):
    FACTORY_FOR = 'appname.Country'
    FACTORY_DJANGO_GET_OR_CREATE = ('cc',)

    cc = "US"
    name = "United States"

假设cc字段是唯一标识符。在

另一个黑客解决方案是重写工厂的create方法,通过查询和缓存结果来搜索对象。在

这个简单的示例不过滤**kwargs,但是:

class StaticFactory(SQLAlchemyModelFactory):                        

    counter = 0                                                     
    cache = []                                                      
    model = None                                                    

    @classmethod                                                    
    def create(cls, **kwargs):                                      
        if not cls.cache:                                           
            cls.cache = your_session.query(cls.model).all()     
        instance = cls.cache[cls.counter]                           
        cls.counter = (cls.counter + 1) % len(cls.cache)            
        return instance                                             

相关问题 更多 >