2013-10-02 4 views
8

मैं परीक्षण फिक्स्चर बनाने के लिए factory_boy का उपयोग कर रहा हूं। मेरे पास दो सरल कारखानियां हैं, जो एसक्लाक्लेमी मॉडल द्वारा समर्थित हैं (नीचे सरलीकृत)।factory_boy कारखानों के साथ डुप्लिकेट से बचें

मैं कई बार 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") 

मेरा प्रश्न है: कैसे मैं इन कारखाने स्थापित कर सकते हैं कि factory_boy एक नया देश हर बार यह एक पता बनाता है बनाने की कोशिश नहीं कर रहा है तो?

+0

आप ([factory.alchemy] पर एक नज़र https://github.com/rbarrois/factory_boy/blob/master/factory ली /alchemy.py)? – javex

+0

सुनिश्चित नहीं है कि आप उस लिंक में क्या संदर्भ दे रहे हैं; उस विशिष्ट फ़ाइल में कुछ भी नहीं है जो उपयोगी लगता है। मैंने फ़ैक्टरी_बॉय और विशेष रूप से स्क्लाक्लेमी फैक्ट्री के लिए दस्तावेज़ों को देखा है, लेकिन मैंने रिकॉर्ड्स का पुन: उपयोग करने के बारे में कुछ भी नहीं देखा है। मूल रूप से "ढूंढें या बनाएं" प्रकार की कार्यक्षमता की तलाश में। –

+0

इसमें अधिक शोध करने के बाद, संक्षिप्त जवाब यह है कि आप इसे नहीं कर सकते हैं। [Django मॉडल के साथ मिल-या-निर्माण] के लिए समर्थन है (https://factoryboy.readthedocs.org/en/latest/orms.html#factory.django.DjangoModelFactory.FACTORY_DJANGO_GET_OR_CREATE), लेकिन SQLAlchemy नहीं। मैं इस सवाल को खुला छोड़ रहा हूं क्योंकि मैं इन दिनों में से किसी एक के लिए स्क्लेक्लेमी समर्थन जोड़ने की उम्मीद कर रहा हूं यदि कोई मुझे इसके लिए धड़कता नहीं है। –

उत्तर

4

नवीनतम कारखाने में लड़का == 2.3.1 में आप जोड़ सकते हैं 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" 

सीसी क्षेत्र मान लिया जाये कि अद्वितीय पहचानकर्ता है।

+0

जैसा कि मैंने उपरोक्त मेरे प्रश्न और अनुवर्ती टिप्पणी में उल्लेख किया है, मैं स्क्लेक्लेमी का उपयोग कर रहा हूं। मुझे पता है कि यह Django के लिए मौजूद है, लेकिन यह मेरी मदद नहीं करता है। जिस कार्यक्षमता को मैं ढूंढ रहा हूं वह कारखाने के लड़के में मौजूद नहीं है, और मेरे पास अभी भी इसे जोड़ने का समय नहीं है। –

2

तुम सही हो, वहीं होता है कि SQLAlchemy आधारित कारखानों के लिए कोई get_or_create समारोह, अगर वस्तुओं आप एक विदेशी कुंजी के रूप में उपयोग करना चाहते हैं पहले से ही मौजूद है, तो आप उन के माध्यम से पुनरावृति कर सकते हैं:

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

तो कल्पना कीजिए कि आप आलसी विशेषता का उपयोग कर अपने फैक्ट्री में एक समाधान को एक साथ जोड़ सकते हैं जो पहली बार जांचता है कि ऑब्जेक्ट डीबी में मौजूद है या नहीं, और यदि ऐसा है तो यह उनके माध्यम से पुन: प्रयास करने के लिए इस विधि का उपयोग करता है, लेकिन यदि ऑब्जेक्ट मौजूद नहीं है, तो यह कॉल करता है पहले ऑब्जेक्ट बनाने के लिए SubFactory

+0

यह निश्चित रूप से एक हैकी समाधान है, अगर आप एक पीआर जमा करते हैं तो एसक्यूएलकेमी के लिए get_or_create क्षमता जोड़ना ;-) –

0

एक और हैकी समाधान कारखाने के 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            
संबंधित मुद्दे