2010-09-02 15 views
11

मैं एसक्लाक्लेमी का उपयोग कर रहा हूं, और मेरे ऑब्जेक्ट मॉडल में कई कक्षाओं में एक ही दो विशेषताएं हैं: आईडी और (पूर्णांक & प्राथमिक कुंजी), और नाम (एक स्ट्रिंग)। मैं उन्हें हर वर्ग में घोषित करने से बचने की कोशिश कर रहा हूं:SQLAlchemy: घोषणात्मक शैली वर्ग परिभाषा में पुनरावृत्ति से बचने

class C1(declarative_base()): 
    id = Column(Integer, primary_key = True) 
    name = Column(String) 
    #... 

class C2(declarative_base()): 
    id = Column(Integer, primary_key = True) 
    name = Column(String) 
    #... 

ऐसा करने का एक अच्छा तरीका क्या है? मैंने मेटाक्लास का उपयोग करने की कोशिश की लेकिन यह अभी तक काम नहीं कर सका।

उत्तर

9

आप एक mixin class में अपने सामान्य विशेषताएं को अलग कर सकता है, और गुणा declarative_base() के साथ-साथ यह वारिस:

from sqlalchemy import Column, Integer, String 
from sqlalchemy.ext.declarative import declarative_base 

class IdNameMixin(object): 
    id = Column(Integer, primary_key=True) 
    name = Column(String) 

class C1(declarative_base(), IdNameMixin): 
    __tablename__ = 'C1' 

class C2(declarative_base(), IdNameMixin): 
    __tablename__ = 'C2' 

print C1.__dict__['id'] is C2.__dict__['id'] 
print C1.__dict__['name'] is C2.__dict__['name'] 

संपादित: आप इस में C1 और C2 साझा करने में एक ही Column वस्तुओं परिणाम होगा सोच सकते हैं, लेकिन जैसा कि SQLAlchemy docs में उल्लेख किया गया है, मिक्स्ड क्लास से उत्पन्न होने पर कॉलम ऑब्जेक्ट्स कॉपी किए गए हैं। मैंने इस व्यवहार को प्रदर्शित करने के लिए कोड नमूना अद्यतन किया है।

+0

दुर्भाग्य से, यह काम नहीं करेगा क्योंकि आईडी विशेषता को IdNameMixin के सभी उप-वर्गों में साझा किया जाएगा। स्क्लेक्लेमी में, प्रत्येक वर्ग में अपनी आईडी (कक्षा कॉलम का एक नव निर्मित वस्तु) होना चाहिए। – max

+1

आम तौर पर आप सही होंगे, लेकिन मेरा अद्यतन उत्तर देखें। – dhaffey

+0

आह बहुत अच्छा !! धन्यवाद। अब अगर मैं केवल '__tablename__' के बारे में कुछ कर सकता हूं, जो निश्चित रूप से अद्वितीय होना चाहिए :) लेकिन मुझे अपने मेटाक्लास संशोधन से बेहतर मिश्रण श्रेणी के साथ आपका दृष्टिकोण पसंद है। – max

1

मुझे लगता है कि मुझे यह काम करने के लिए मिला है।

मैंने एक मेटाक्लास बनाया जो डेक्लेरेटिव मेटा से निकला, और सी 1 और सी 2 के मेटाक्लास को बनाया। उस नए मेटाक्लास में, मैंने बस कहा

def __new__(mcs, name, base, attr): 
    attr['__tablename__'] = name.lower() 
    attr['id'] = Column(Integer, primary_key = True) 
    attr['name'] = Column(String) 
    return super().__new__(mcs, name, base, attr) 

और ऐसा लगता है कि यह ठीक काम करता है।

2

क्या आप कॉलम की कॉपी विधि का भी उपयोग कर सकते हैं? इस तरह, फ़ील्ड को टेबल के स्वतंत्र रूप से परिभाषित किया जा सकता है, और जिन क्षेत्रों का पुन: उपयोग किया जाता है वे सिर्फ field.copy() - ed हैं।

id = Column(Integer, primary_key = True) 
name = Column(String) 

class C1(declarative_base()): 
    id = id.copy() 
    name = name.copy() 
    #... 

class C2(declarative_base()): 
    id = id.copy() 
    name = name.copy() 
    #... 
+0

कोई भी जानता है कि विभिन्न तालिका वर्गों में उन स्तंभों के गुणों को कैसे बदला जाए? यही है, यदि आईडी सी 1 में प्राथमिक नहीं है, लेकिन सी 2 में प्राथमिक है, तो हम उस पुनरावृत्ति के बिना उस भेद को कैसे बनाते हैं जिसे हम टालना चाहते हैं? – jkmacc

संबंधित मुद्दे