2012-01-19 12 views
5

Puedo ejecutar normalmente SQLAlchemy cuando todo está en un archivo. Ahora quiero poner mi modelo en otro archivo.Compartir Declarative_Base (SQLAlchemy) con Singleton en Python

Sin embargo, esto no funciona porque no puedo encontrar una forma de compartir la base. Intenté con un Singleton pero es nulo en model.py y el esquema nunca se crea en la base de datos.

¿Cómo puedo hacer para solucionar esto?

Mis archivos (versión simplificada):

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

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

modelo/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) 

EDITAR @Lafaya

me cambió model/__init__.py así:

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

Luego cambié model/model.py así:

from model import Base 

class User(Base): 
    etc... 

ahora no puedo importar la base de model.py (porque ya se importa por __init.py__). ¡Pero necesito una referencia 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 

Respuesta

4

Escribir el Base__init__.py en el paquete de modelo. Entonces puedes importarlo y usarlo.

Jut poner Base en model/__init__.py.

+0

Mi respuesta en la edición posterior – Yohann

+0

Ok, finalmente pu el modelo en el __init__.py – Yohann

Cuestiones relacionadas