On Sep 23, 2013, at 10:56 AM, Michael Bayer <mike...@zzzcomputing.com> wrote:
> > On Sep 22, 2013, at 11:47 PM, Donald Stufft <donald.stu...@gmail.com> wrote: > >> Mostly I'm trying to avoid global state like metadata. > > irony....the purpose of MetaData is to *avoid* global state. If any Table > could refer to ForeignKey("someothertable.id"), without MetaData it means > SQLAlchemy would need to have a truly global registry of all tables > everywhere (it would also be disastrous as far as naming in large and/or > multi-tenancy style apps). It would also make create_all() etc. very > painful. > > >> The Tables themselves are global, but I feel like the metatdata maybe >> shouldn't be? > > MetaData and Table are both objects. Feel free to put them in some context > that you pass around everywhere. MetaData itself has all the Table objects > inside of metadata.tables too. > > I never really write Core-only apps in the first place (since it sounds like > we aren't talking about any mapped classes) so I don't know that there's > really an official pattern here. Of course historically, having Table > objects as global seems fairly natural but I'm not as allergic to "global" > state as other folks. > > >> I'm not a SQL alchemy expert so maybe what I'm trying to do is crazy and the >> answer is don't do that. Mostly I'm trying to figure out what patterns are >> best for testable apps written with SQL alchemy. > > yeah pretty soon I'm going to have to full on go after this "global == not > testable" thing. I see no evidence for this at all, and the "globals aren't > testable" orthodoxy makes the incredibly common and useful registry pattern > (http://martinfowler.com/eaaCatalog/registry.html) not really possible. My > Pycon talk in 2014 (assuming it's accepted) will illustrate some simple test > patterns where global Session registries are involved. > > > Well mostly I've isolated other pieces of global state and while metadata itself probably isn't a problem I was hesitant to add it as a piece of global state since I didn't have anything else like that. I did come up with a solution though that I think works Ok. It's basically allowing me to declare my tables at the top level (but not use them from there) so that I can organize my code better, but then the "real" tables exist inside of my application object where I can use them. Examples here: https://github.com/dstufft/warehouse/blob/werkzeug/warehouse/packaging/models.py https://github.com/dstufft/warehouse/blob/werkzeug/warehouse/models.py https://github.com/dstufft/warehouse/blob/werkzeug/warehouse/application.py#L37-L46 I haven't settled on this approach (notably I need to figure out how it's going to interact with alembic) but so far It seems to work alright. ----------------- Donald Stufft PGP: 0x6E3CBCE93372DCFA // 7C6B 7C5D 5E2B 6356 A926 F04F 6E3C BCE9 3372 DCFA
signature.asc
Description: Message signed with OpenPGP using GPGMail