2012-05-20 4 views
2

Je travaille sur une application serveur Python utilisant SQLAlchemy pour l'accès à la base de données. Je voudrais avoir des objets moteur, session et métadonnées dans un module meta.py qui sont utilisés dans le programme pour accéder à la base de données (comme la convention Pylons).Comment modifier les objets de niveau module en Python? (comme les méta-objets Pylons)

Les objets de moteur et de session sont initialisés sous la forme None dans le module meta.py, puis sont réellement affectés à des valeurs réelles dans d'autres modules. Par exemple.

model/meta.py:

engine = None 
Session = None 
metadata = Metadata() 

model/__init__.py:

from simplesite.model import meta 

def init_model(): 
    # ... 
    sm = orm.sessionmaker(...) 
    meta.Session = orm.scoped_session(sm) 

Le problème est quand j'importer et exécuter init_model() dans un autre module, puis importer session de meta.py, il est toujours réglé sur Aucun. C'est à dire.

from model.meta import Session 
from model import init_model 

init_model() 
# Session is still None! 

Quelqu'un pourrait me dire pourquoi c'est et/ou comment cela fonctionne dans les applications Pylons? Je suppose que la réponse serait quelque chose de plus fondamental sur le fonctionnement de Python?

D'autres suggestions sur la façon d'avoir un seul point d'accès à la base de données dans une application seraient également appréciées (c'est-à-dire les meilleures pratiques pour utiliser SQLAlchemy dans les grandes applications).

+3

Ce que vous faites est très bien. Le problème est que 'from model.meta import Session' lie la valeur dans' meta.Session' au nom 'Session', qui ne change pas quand le nom' meta.Session' change. Au lieu de cela, faites simplement 'à partir du modèle import meta', puis recherchez' Session' comme 'meta.Session'. – katrielalex

+2

En fait, pensez à quel point il serait désagréable si le code d'un autre module pouvait _changer vos variables locales_ !! – katrielalex

+0

Merci, c'était la réponse que je cherchais. J'utilise maintenant du méta d'importation de modèle, puis référence à l'objet par meta.Session et cela fonctionne – user1405990

Répondre

1

Je réponds à cela car il semble que ce soit juste assis ici, bien qu'une réponse ait été donnée dans les commentaires par @katrielalex.

Lorsque vous faites from model.meta import Session, vous créez une nouvelle variable locale appelée Session qui est liée à l'objet de ce module. Lorsque init_model() s'exécute, il rétablit le nom dans le module meta, mais cela n'affecte pas votre variable locale.

Vous pouvez obtenir l'effet désiré par l'accès ne meta.Session qu'après init_model() a fait son travail:

from model import meta 
from model import init_model 
init_model() 
Session = meta.Session 
Questions connexes