2015-01-26 5 views
7

बीच आगे और पीछे स्तंभ मान कन्वर्ट मेरी डेटाबेस में, मैं जहां डाटा कुछ अजीब प्रारूप में संग्रहीत किया जाता है कुछ स्तंभ है। चूंकि डेटाबेस को अन्य कोड द्वारा भी प्रयोग किया जाता है, इसलिए भी, मैं डेटा प्रारूप नहीं बदल सकता।SQLAlchemy: आंतरिक और डेटाबेस प्रारूप

उदाहरण के लिए, अजीब स्वरूपों में से एक है कि एक समय मूल्य 23:42:30 की तरह एक स्ट्रिंग के रूप में प्रस्तुत किया जाता है है। मैं कुछ जादू है कि मुझे हमेशा अजगर तरफ datetime.time वस्तुओं का उपयोग करने की अनुमति देता है करना चाहते हैं।

एक बहुत ही सरल समाधान होगा कुछ की तरह:

col_raw = Column('col', String(7)) 

@property 
def col(self): 
    return datetime.strptime(self.col_raw, '%H:%M:%S').time() 
@col.setter 
def colself, t): 
    self.col_raw = t.strftime('%H:%M:%S') 

बहरहाल, यह समस्या सिर्फ डाटा पढ़ने एवं लिखने के लिए हल करती है। इस तरह सामान संभव नहीं होगा: hybrid extension उपयोग करने के लिए

Table.query.filter(Table.col == time(23,42,30)) 

एक और तरीका होगा। इस तरह, पूछताछ संभव होगी, लेकिन अगर मैं इसे सही ढंग से देखता हूं, तो लेखन नहीं होगा। इसके अलावा, इसे पाइथन कोड में एक बार और एक बार SQL कोड में दो बार कोडिंग लिखना आवश्यक है। (अतिरिक्त समस्या: मुझे यकीन नहीं है कि रूपांतरण केवल SQL कोड का उपयोग करके लिखा जा सकता है।)

क्या वास्तव में कोई तरीका नहीं है जो दोनों को जोड़ता है? इस तरह के रूप में मैं दो कार्यों को परिभाषित, SQLAlchemy का उपयोग करता है जो पारदर्शी रूप से स्ट्रिंग और वापस करने के लिए अजगर वस्तु से मूल्यों को परिवर्तित करने के लिए, मान लें कि python2sql और sql2python है? मुझे पता है कि इससे कुछ प्रश्न असंभव होंगे, जैसे between या like या रकम और जैसे, लेकिन यह ठीक है।

कृपया ध्यान रखें कि समय बात केवल उदाहरण मामलों में जहां मैं डेटा बदलने की आवश्यकता से एक है; इसलिए कृपया उत्तर सामान्य रखने की कोशिश करें।

उत्तर

12

type decorator का उपयोग करें जो कस्टम प्रारूप में कनवर्ट करने के लिए हैंडल करता है। अपने कॉलम को परिभाषित करते समय String के बजाय इस प्रकार का उपयोग करें।

class MyTime(TypeDecorator): 
    impl = String 

    def __init__(self, length=None, format='%H:%M:%S', **kwargs) 
     super().__init__(length, **kwargs) 
     self.format = format 

    def process_literal_param(self, value, dialect): 
     # allow passing string or time to column 
     if isinstance(value, basestring): # use str instead on py3 
      value = datetime.strptime(value, self.format).time() 

     # convert python time to sql string 
     return value.strftime(self.format) if value is not None else None 

    process_bind_param = process_literal_param 

    def process_result_value(self, value, dialect): 
     # convert sql string to python time 
     return datetime.strptime(value, self.format).time() if value is not None else None 

# in your model 
class MyModel(Base): 
    time = Column(MyTime(length=7))