On Wed, Dec 28, 2011 at 8:52 AM, Michael Bayer <[email protected]> wrote: > > I would say that's just something library authors would need to know how to > do. They need to understand that transactions are defined by the calling > application, and how a Session relates to that. It's just one click more > complicated than having to know nothing at all about how transactions work. > A convention here, a "how to" document of best practices for 3rd party > stuff, would make it clear how these should be done. Using the transaction > manager recommended with Pyramid would be best, assuming the transaction > manager is capable of this. > > Regarding Base, Base corresponds to a class hierarchy, meaning it's how your > class structure is designed. SQLAHelper doesn't need to change here, it if > course can expose the default "Base" to everyone, and that's great. A shop > that has multiple apps of its own but are designed to work together can > certainly have them all call into SQLAHelper's "Base" and that is fine. > > As far as a 3rd party thing, like "download this library and now you have a > standalone auth model/schema" (is there at least *one* 3rd party thing that > is *not* about auth?), that probably shouldn't use the same Base, as it > implies the app can't assume any kinds of conventions or behaviors on the > Base class, or if it does it means my own app now can't do X, Y, or Z because > it will break the 3rd party library. So I'd rather the standard practice > is to share configuration and namespaces, but not class structure except for > mixins. But if someone shows me an example here why they really want to > share out the Base that of course can make me more aware. > > The sharing of configuration can integrate with the schema of the target > system by sharing MetaData(). It can integrate at the relationship() level > using real class objects, or by sharing _decl_class_registry, which has > always been something that could be monkeypatched, but not public...so > r76d872dc77b9 now contains this feature: > > from sqlalchemy.ext.declarative import declarative_base > > reg = {} > Base1 = declarative_base(class_registry = reg) > Base2 = declarative_base(class_registry = reg) > > class A(Base1): > __tablename__ = 'a' > id = Column(Integer, primary_key=True) > > class B(Base2): > __tablename__ = 'b' > id = Column(Integer, primary_key=True) > aid = Column(Integer, ForeignKey(A.id)) > as_ = relationship("A") > > assert B.as_.property.mapper.class_ is A > > If you additionally share a MetaData() between two bases, now those two will > entirely share the same class name and table name registry. > > Also note ticket 2338: http://www.sqlalchemy.org/trac/ticket/2338 , which I'm > leaning towards, would add the full module path of things to the registry, so > you could say: > > group = relationship("myauth.classes.Group") > >> >> Well, I'm inclined to do whatever MikeB suggests. But what would the >> module contain in this case; i.e., what would its globals be? You'd >> still need a module with globals in order to be a well-known rendevous >> point. 'helper = SQLAHelper()' as a variable in the application >> doesn't do that. Or would 'helper' be the global in the package? > > never mind that part here, if it's a module global already that's fine.
I adjusted the proposal to use globals instead of a class. If I hear no objections in the next couple days, I'll make a SQLAHelper 2 with the new API, but also keeping the old API for backward compatibility. Does anyone know of a better name than 'sqlahelper'? >> One thing SQLAHelper does is that if you call ``add_engine(engine)`` >> without an engine name, it becomes the default engine, and the Session >> and Base.metadata are automatically bound to it. This is so that >> applications with a single database only need to make one function >> call to set everything up. It looks like the only way to do that in >> your 'helper' structure would be a 'helper.set_default_engine()' >> method? And 'helper.engines.default' would be None initially, because >> the engine is not known at import time? > > perhaps helper.engine = some_engine would be the equivalent of > add_engine(engine) - or do we think using a "setter" approach belies that > nothing more than just a simple assignment is going on ? It does more than just setting an attribute, it also modifies other variables (the default base and session). > I would think if the plugin is designed for Pyramid, it would be based around > ZopeSQLAlchemy, which provides a master transaction for everyone to integrate > towards. Do the third party plugins at least integrate with that ? Question: if multiple scoped sessions are created, each using ZopeTransactionExtension, would they all automatically fit into the global commit/rollback? Can we use the same ZopeTransactionExtension *instance* for all the scoped sessions, or would they each need a separate instance? > Also, just as a note, I've never seen a 3rd party plugin that uses SQLAlchemy > before, which is using a Session, defining tables, etc. Can I see one ? > Are there a lot , or like half a dozen ? I can't remember everywhere I've seen things. There are few libraries using SQLAlchemy yet. I mainly wanted to avoid a future mess if everyone did things in different ways, and then had trouble interoperating. The API you've suggested sounds the most flexible; it won't get into anyone's way but it's there if you want it, and it can scale to multiple datbases, Bases, and Sessions. Libraries can be documented to either use the default Session, a specific named Session, or to take an attribute name specifying which Session to use. And the user can set ``sqlahelper.sessions.library = sqlahelper.sessions.default`` to force a library to share a session (or base or engine) if it's not set up to do so. -- Mike Orr <[email protected]> -- You received this message because you are subscribed to the Google Groups "pylons-discuss" group. To post to this group, send email to [email protected]. To unsubscribe from this group, send email to [email protected]. For more options, visit this group at http://groups.google.com/group/pylons-discuss?hl=en.
