2012-01-19 24 views
5

Tôi có thể chạy bình thường SQLAlchemy khi mọi thứ nằm trong một tệp. Bây giờ tôi muốn đặt mô hình của mình vào một tệp khác.Chia sẻ Declarative_Base (SQLAlchemy) với Singleton trong Python

Tuy nhiên, điều này không hiệu quả vì tôi không thể tìm cách chia sẻ cơ sở. Tôi đã thử với Singleton nhưng nó là Null trong model.py và lược đồ không bao giờ được tạo trong cơ sở dữ liệu.

Làm cách nào để khắc phục sự cố này?

My files (phiên bản đơn giản):

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

chính/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 

mô hình/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) 

EDIT @Lafaya

tôi đã thay đổi model/__init__.py như thế:

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

Sau đó, tôi đã thay đổi model/model.py như thế:

from model import Base 

class User(Base): 
    etc... 

Bây giờ tôi không thể nhập cơ sở từ model.py (vì nó được nhập bằng aleady bởi __init.py__). Nhưng tôi cần một tham chiếu đến Base!

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 

Trả lời

4

Viết Base trong gói __init__.py của gói mô hình. Sau đó, bạn có thể nhập và sử dụng nó.

Đay đặt Base trong model/__init__.py.

+0

Câu trả lời của tôi trong bài chỉnh sửa – Yohann

+0

Ok, tôi cuối cùng là pu mô hình trong __init__.py – Yohann

Các vấn đề liên quan