2012-03-07 12 views
12

इसलिए मेरे पास स्क्लाक्लेमी का उपयोग करके तालिकाओं का एक समूह है जिसे परिणामस्वरूप ऑब्जेक्ट के रूप में मॉडलिंग किया जाता है जो परिणाम से declarative_base() पर कॉल करता है। अर्थात्:स्क्लेल्चेमी: एकाधिक विरासत से बचने और सार आधार वर्ग

Base = declarative_base() 

class CommonRoutines(object): 
    @classmethod 
    def somecommonaction(cls): 
     # body here 

class Table1(CommonRoutines, Base): 
    # __tablename__ & such here 

class Table2(CommonRoutines, Base): 
    # __tablename__ & such here 

बात मुझे पसंद नहीं है:

Base = declarative_base() 
class Table1(Base): 
    # __tablename__ & such here 

class Table2(Base): 
    # __tablename__ & such here 

आदि मैं तो कुछ सामान्य कार्यक्षमता मेरी डीबी तालिका वर्गों में से प्रत्येक के लिए उपलब्ध करना चाहते थे, the easiest way to do this according to the docs सिर्फ एकाधिक वंशानुक्रम करना है इसके बारे में ए) सामान्य रूप से एकाधिक विरासत थोड़ा सा है (super() कॉल इत्यादि जैसी मुश्किल हल करने वाली चीजें मिलती है), बी) यदि मैं एक नई तालिका जोड़ता हूं तो मुझे Base और CommonRoutines और सी) से उत्तराधिकारी को याद रखना होगा। "कॉमनराउटिन" वर्ग "एक-एक" तालिका में एक प्रकार का अर्थ है। वास्तव में CommonBase एक सार आधार वर्ग है जो फ़ील्ड & दिनचर्या के सेट को परिभाषित करता है जो सभी तालिकाओं के लिए आम हैं। एक और तरीका रखो: "इसकी-एक" सारणी सारणी।

तो, मैं क्या करना चाहते हैं यह है:

Base = declarative_base() 

class AbstractTable(Base): 
    __metaclass__ = ABCMeta # make into abstract base class 

    # define common attributes for all tables here, like maybe: 
    id = Column(Integer, primary_key=True) 

    @classmethod 
    def somecommonaction(cls): 
     # body here 

class Table1(AbstractTable): 
    # __tablename__ & Table1 specific fields here 

class Table2(AbstractTable): 
    # __tablename__ & Table2 specific fields here 

लेकिन निश्चित रूप से यह काम नहीं करता, जैसा कि मैंने तो एक के लिए है) एक AbstractTable के लिए __tablename__, बी) एबीसी चीजों के पहलू को परिभाषित सिरदर्द के सभी प्रकारों का कारण बनता है, और सी) को AbstractTable और प्रत्येक व्यक्तिगत तालिका के बीच कुछ प्रकार के डीबी रिश्ते को इंगित करना होता है।

तो मेरा प्रश्न: क्या यह उचित तरीके से हासिल करना संभव है? आदर्श रूप में मैं लागू करने के लिए करना चाहते हैं:

  • कोई एकाधिक वंशानुक्रम
  • CommonBase/AbstractTable हो सार (यानी instantiated नहीं किया जा सकता है)

उत्तर

14

यह बहुत straigh से आगे है, तो आप सिर्फ declarative_base() बनाने के वापस जाने के लिए एक Base कक्षा जो से cls= पैरामीटर का उपयोग कर विरासत में प्राप्त होती है। Augmenting The Base दस्तावेज़ों में भी दिखाया गया है।

class CommonBase(object): 
    @classmethod 
    def somecommonaction(cls): 
     # body here 

Base = declarative_base(cls=CommonBase) 

class Table1(Base): 
    # __tablename__ & Table1 specific fields here 

class Table2(Base): 
    # __tablename__ & Table2 specific fields here 
+0

मुझे सही अगर मैं गलत हूँ, लेकिन उन "AbstractTable" विरासत "बेस" दिखाई देनी चाहिए, सही? (यानी 'कक्षा तालिका 1 (आधार): ') –

+0

@ एडमपार्किन: ज़ाहिर है। ठीक कर दिया। – van

+0

हाँ, यह वही था जो मैं ढूंढ रहा था। धन्यवाद! दृष्टिकोण के लिए एकमात्र कमी यह है कि अब 'कॉमनबेस' वर्ग की '__init__' को कॉल नहीं किया जाता है (' declarative_base' एक ऐसी कक्षा का उत्पादन करता है जो 'सुपर' को '__init__' में नहीं कहता है, इसलिए पायथन के सहकारी एकाधिक विरासत तंत्र नहीं हैं काम)। हम्म .... –

2

आप एक absract बेस मॉडल बनाने के लिए AbstractConcreteBase उपयोग कर सकते हैं:: अपने कोड तो नीचे के समान लग सकता है

from sqlalchemy.ext.declarative import AbstractConcreteBase 


class AbstractTable(AbstractConcreteBase, Base): 
    id = db.Column(db.Integer, primary_key=True) 

    @classmethod 
    def somecommonaction(cls): 
     # body here 
26

SQLAlchemy संस्करण 0.7.3 शुरू की __abstract__ निर्देश जो सार कक्षाओं के लिए प्रयोग किया जाता है कि डेटाबेस डेटाबेस में मैप नहीं किया जाना चाहिए, भले ही वे sqlalchemy.ext.declarative.api.base के उप-वर्ग हैं। तो अब आप इस तरह एक आधार वर्ग बनाने के लिए:

Base = declarative_base() 

class CommonRoutines(Base): 
    __abstract__ = True 

    id = Column(Integer, primary_key=True) 

    def __init__(self): 
     # ... 

सूचना कैसे CommonRoutines एक __tablename__ विशेषता नहीं है। तो फिर इस तरह उपवर्गों बनाएँ:

class Foo(CommonRoutines): 
    __tablename__ = 'foo' 

    name = Column(...) 

    def __init__(self, name): 
     super().__init__() 
     self.name = name 
     # ... 

इस तालिका में foo करने के लिए नक्शे और CommonRoutines से id विशेषता प्राप्त कर लेगा।

स्रोत और अधिक जानकारी: http://docs.sqlalchemy.org/en/rel_0_7/orm/extensions/declarative.html#abstract

+0

यह वही था जो मैंने वास्तव में देखा था। धन्यवाद – pylover

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