On Tue, Dec 27, 2011 at 8:05 AM, Michael Bayer <[email protected]> wrote:
> What's the use case for a Base being shared to a third party module that 
> doesn't know about your application?  This sounds like a bad idea.   A Base 
> might have any number of behaviors on it, like certain columns, naming 
> conventions, __mapper_args__(), attribute names, that can't be anticipated by 
> a third party library.

The problem is that applications and libraries are all creating their
own Bases and Sessions, and then it becomes complicated to make them
work together. So we need to figure out some common way to handle
this, so that they can all cooperate, and the application can make the
library use its Session and Base if it wants to. Because some
libraries are just defining a few tables with a name prefix, and don't
need a separate database.

> That said I have a feeling some libraries are already doing this but I wish 
> we could work out a better way than using inheritance as a third party plugin 
> point - one of Ben's key rationales for dumping Pylons altogether is that it 
> was built on this model for extensibility.

Ben has also been recommending SQLAHelper.

Originally SQLAHelper was created to avoid circular imports or a
'meta' module in the model. Pylons used a 'model.meta' module to hold
the Session, Base, and engine. We wanted to avoid that in Pyramid, but
we also wanted to avoid defining the Session and Base in
model.__init__, which submodules would import, thus creating a
circular import. So SQLAHelper replaced the 'meta' module, and because
it's preinitialized so it can be imported at any time. The issue about
how it could also help in this cooperation between the application and
libraries was discovered later.

>> But when you start getting multiple databases in the
>> application, it may get beyond what the shared Base can provide. In
>> that case, you can decide whether one database is general-purpose,
>> used by several modules and third-party libraries, while another
>> database is single-purpose, used only by one module. Then there's a
>> clear answer: use SQLAHelper's Base for the shared database, and your
>> own Base for the single-purpose database. For instance, the second
>> database may be specifically for site statistics, searching, an
>> external database you're consulting, etc. These would all be
>> single-purpose databases, which wouldn't have to be shared.
>
> Why not standardize SQLAHelper on a "one by default, many if desired" model ? 
>    Also as an alternative to the getter/setter style, why not just:
>
> helper = SQLAHelper()
>
> # default objects: "base", "session", "engine":
>
> default_base = helper.base
> default_session = helper.session
> helper.engine = create_engine(...)
>
> # namespaces for each, "default" points to the "default":
>
> helper.bases.default is helper.base
> helper.sessions.default is helper.session
> helper.engines.default is helper.engine
>
> # alternates to the "default":
>
> helper.bases.generic_base = Base()
> helper.sessions.alternate_session = scoped_session(...)
> helper.engines.alt1 = create_engine(...)
>
>
> I think multiple sessions should be supported.  My current app uses two 
> simultaneously as many classes are represented in two different databases at 
> the same time - one is the "live" database the other is "historical".    An 
> application that switches between "master" and "slave" databases at the 
> session level needs to do this also.

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?

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?

-- 
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.

Reply via email to