2012-01-19 17 views
5

Posso eseguire normalmente SQLAlchemy quando tutto è in un unico file. Ora voglio mettere il mio modello in un altro file.Condividi Declarative_Base (SQLAlchemy) con Singleton in Python

Tuttavia, questo non funziona perché non riesco a trovare un modo per condividere la base. Ho provato con un Singleton ma è Null in model.py e lo schema non viene mai creato nel database.

Come posso risolvere questo problema?

miei file (versione semplificata):

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

principale/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 

modello/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

ho cambiato model/__init__.py così:

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

poi ho cambiato model/model.py così:

from model import Base 

class User(Base): 
    etc... 

ora non posso importare Base da model.py (perché importa già da __init.py__). Ma ho bisogno di un riferimento a 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 

risposta

4

Scrivi la Base nel __init__.py del pacchetto di modello. Quindi puoi importarlo e usarlo.

Jut put Base in model/__init__.py.

+0

La mia risposta in post edit – Yohann

+0

Ok, finalmente posso il modello in __init__.py – Yohann