2013-10-02 16 views
8

Tôi đang sử dụng factory_boy để tạo các đồ đạc thử nghiệm. Tôi có hai nhà máy đơn giản, được hỗ trợ bởi các mô hình SQLAlchemy (được đơn giản hóa bên dưới).Tránh trùng lặp với các nhà máy factory_boy

Tôi muốn có thể gọi AddressFactory.create() nhiều lần và tạo nó Country nếu chưa có, nếu không tôi muốn sử dụng lại bản ghi hiện có.

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") 

Câu hỏi của tôi là: làm thế nào tôi có thể thiết lập các nhà máy để factory_boy mà không cố gắng để tạo ra một mới Nước mỗi khi nó tạo ra một địa chỉ?

+0

Bạn hãy nhìn vào [factory.alchemy] (https://github.com/rbarrois/factory_boy/blob/master/factory /alchemy.py)? – javex

+0

Không chắc chắn những gì bạn đang đề cập đến trong liên kết đó; không có gì trong tệp cụ thể có vẻ hữu ích. Tôi đã xem xét các tài liệu cho factory_boy và nhà máy SQLAlchemy nói riêng, nhưng tôi đã không thấy bất kỳ điều gì về việc sử dụng lại các bản ghi. Về cơ bản tìm kiếm một chức năng "tìm hoặc tạo". –

+0

Sau khi nghiên cứu thêm về điều này, câu trả lời ngắn gọn là bạn không thể làm điều đó. Có hỗ trợ cho [get-or-tạo với mô hình Django] (https://factoryboy.readthedocs.org/en/latest/orms.html#factory.django.DjangoModelFactory.FACTORY_DJANGO_GET_OR_CREATE), nhưng không phải SQLAlchemy. Tôi để lại câu hỏi này mở vì tôi hy vọng sẽ thêm hỗ trợ SQLAlchemy cho một trong những ngày này nếu không ai đánh tôi với nó. –

Trả lời

4

Trong nhà máy-boy mới nhất == 2.3.1 bạn có thể thêm FACTORY_DJANGO_GET_OR_CREATE

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

    cc = "US" 
    name = "United States" 

Giả lĩnh vực cc là định danh duy nhất.

+0

Như tôi đã đề cập trong câu hỏi của tôi và followup bình luận ở trên, tôi đang sử dụng SQLAlchemy. Tôi biết điều này tồn tại cho Django, nhưng điều đó không giúp tôi. Chức năng tôi đang tìm kiếm không tồn tại ở nhà máy, và tôi vẫn chưa có thời gian để thêm nó. –

2

Trong khi bạn nói đúng rằng không có get_or_create chức năng cho các nhà máy SQLAlchemy dựa trên, nếu các đối tượng bạn muốn sử dụng như một chìa khóa nước ngoài đã tồn tại, bạn có thể lặp qua chúng:

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

Vì vậy, bạn có thể cùng nhau giải quyết một giải pháp trong nhà máy của bạn bằng cách sử dụng thuộc tính lười để kiểm tra xem đối tượng tồn tại trong db hay không, và nếu như vậy nó sử dụng phương thức này để lặp qua chúng, nhưng nếu đối tượng không tồn tại, nó gọi SubFactory để tạo đối tượng đầu tiên.

+0

Đây chắc chắn là một giải pháp hacky, tốt hơn nhiều nếu bạn gửi một PR thêm khả năng get_or_create cho SQLAlchemy ;-) –

0

Giải pháp hacky khác là ghi đè phương thức create của nhà máy theo cách mà đối tượng được tìm kiếm bằng truy vấn và lưu vào bộ nhớ cache kết quả.

ví dụ đơn giản này không có lọc trên **kwargs mặc dù:

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            
Các vấn đề liên quan