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

Attachment: signature.asc
Description: Message signed with OpenPGP using GPGMail

Reply via email to