2012-01-19 3 views
5

में सिंगलटन के साथ Declarative_Base (SQLAlchemy) साझा करें I सब कुछ एक फ़ाइल में होने पर सामान्य रूप से SQLAlchemy चला सकता है। अब मैं अपना मॉडल किसी अन्य फाइल में रखना चाहता हूं।पाइथन

हालांकि, यह काम नहीं करता है क्योंकि मुझे आधार साझा करने का कोई तरीका नहीं मिल रहा है। मैंने सिंगलटन के साथ प्रयास किया लेकिन यह model.py में शून्य है और स्कीमा डेटाबेस में कभी नहीं बनाया गया है।

मैं इसे ठीक करने के लिए कैसे कर सकता हूं?

मेरे फ़ाइलें (सरलीकृत संस्करण):

 - /main/__init__.py 
    - /main/main.py 
    - /utils/__init__.py 
    - /utils/utils.py 
    - /model/__init__.py 
    - /model/model.py 

मुख्य/main.py:

from model import User 
from utils.utils import readConf,createSession,getBase 

class Worker(threading.Thread): 

    def __init__(self, queue, session): 
     self.__queue = queue 
     threading.Thread.__init__(self) 
     self._stopevent = threading.Event() 

    def run(self): 
     session.merge(User(queue.get())) 
     session.commit() 


class Collector(threading.Thread): 

    def __init__(self, nom = ''): 
     threading.Thread.__init__(self) 
     self.nom = nom 
     self._stopevent = threading.Event() 


    def run(self): 
     while not self._stopevent.isSet(): 
      queue.put("Name") 

if __name__ == '__main__': 
    conf = readConf("file.") 
    session = createSession(conf) 
    queue = Queue.Queue(0)  
    Worker(queue, session).start() 
    Collector("Start").start() 

utils/utils.py

from sqlalchemy.ext.declarative import declarative_base 
from sqlalchemy.schema import MetaData 

def createSession(conf): 
    schema = conf['bdd']['type'] + '://' + conf['bdd']['user'] + ':' + conf['bdd']['password'] + '@' + conf['bdd']['host'] + '/' + conf['bdd']['db'] 
    engine = create_engine(schema, echo=True) 

    b = getBase("Utils") 
    b.set_base(declarative_base()) 

    Base = b.get_base()  
    Base.metadata.create_all(engine)  

    Session = sessionmaker(bind=engine) 
    session = Session() 
    return session 

class getBase(object): 
    __single = None # the one, true Singleton 
    __base = None 
    __text = None 
    __base = None 

    def __new__(cls, *args, **kwargs): 
     # Check to see if a __single exists already for this class 
     # Compare class types instead of just looking for None so 
     # that subclasses will create their own __single objects 
     if cls != type(cls.__single): 
      cls.__single = object.__new__(cls, *args, **kwargs) 
      __base = declarative_base() 

     return cls.__single 

    def __init__(self,name=None): 
     self.name = name 

    def get_base(self): 
     return self.__base 


    def set_base(self, value): 
     self.__base = value 

मॉडल/model.py

from utils.utils import getBase 

b = getBase("model") 
b.set_base(declarative_base()) 
Base = b.get_base() 

class User(Base): 
    __tablename__ = 'users' 

    def __init__(self, name): 
     self.screen_name = name 

    name_id = Column(Integer, primary_key=True, autoincrement=True) 
    screen_name = Column(BigInteger(), primary_key=True, nullable=False) 

संपादित @Lafaya

मैं model/__init__.py उस तरह बदल दिया है:

#!/usr/bin/python 
Base = declarative_base() 

तो मैं बदल model/model.py इस तरह:

from model import Base 

class User(Base): 
    etc... 

अब मैं model.py से बेस आयात नहीं कर सकते (क्योंकि यह __init.py__ द्वारा आयातित आयात)। लेकिन मुझे बेस के संदर्भ की जरूरत है!

Traceback (most recent call last): 
    File "../main/main.py", line 12, in <module> 
    from model.model import User 
    File "../model/model.py", line 3, in <module> 
    from model import Base 
ImportError: cannot import name Base 

उत्तर

4

मॉडल पैकेज का __init__.py में Base लिखें। फिर आप इसे आयात कर सकते हैं और इसका इस्तेमाल कर सकते हैं।

जूट Basemodel/__init__.py में डाल दें।

+0

पोस्ट संपादित करने में मेरा उत्तर – Yohann

+0

ठीक है, मैं आखिर में __init__.py में मॉडल को पु – Yohann