On Sep 27, 2011, at 1:21 PM, Chris Withers wrote: > On 27/09/2011 18:10, Michael Bayer wrote: >> >>> That looks like it should ship with SA itself... >>> >>> Does it? >> >> on the website, sure :) >> >> Many of these things are better as recipes > > Meh, that used to be true of mixins. > I'm very glad that's now in the core. >
(Note to readers: Chris and I hang out each year at Pycon. He's a great guy, so forgive the colloquial tone I take with him !) > The trouble with keeping this as a recipe is that if you want to use it > anywhere seriously, *every* project you want to use it on you have to: > > - find somewhere to put it OK you should check out my talk: http://techspot.zzzeek.org/2011/09/25/sqlalchemy-an-architectural-retrospective/ it's a core value of SQLAlchemy that if you are writing a non-trivial application, you should always have a foundation which includes those idioms you're going to build on. SQLAlchemy doesn't provide idioms out of the box, just the tools to create them and plenty of examples and guidance. > - write unit tests for for you would have unit tests against your models being able to persist data to and from the database. The functionality of mapping and reflecting would be rolled into that automatically so no additional tests are needed. > - try and remember why it's slightly different in one project than another if you have two projects - one uses reflection to do everything, the other doesn't, those two projects are already going to be slightly different - except one will have this weird "mymodel.prepare()" call buried deep inside of it. With the recipe being something explicit, its easier to see that project B is doing things differently. > - generally end up cursing and swearing... you need to get over that > >> - it is easier for us to support just the "__mapper_cls__" argument rather >> than a full usage pattern. > > Why? How would the "full usage pattern" differ? Generally when I come up with a recipe to solve a problem in 5 minutes, its not ready to be a core feature. If it becomes the prominent way to do things, we would need to ensure that all other methods are de-emphasized, etc. This recipe in particular builds upon a set of APIs, especially that it conceals Table(..., autoload=True) that makes it extremely dangerous to confuse people with. Declarative already has an attribute called __autoload__, which I yanked out of the docs. You can already say __table__ = Table(..., autoload=True), and __autoload__ was redundant and less-featured. Users who needed to reflect the Table, use declarative, but also needed to customize the Table a bit as described at http://www.sqlalchemy.org/docs/core/schema.html#overriding-reflected-columns would be totally confused by __autoload__, it hides what should be obvious. User comes to SQLAlchemy, wants to autoload a database and map to it. Right now, the path is clear - understand that you're mapping to a Table, understand how to autoload a Table, understand how to apply it to a mapping. One way, everyone gets it. New way is introduced, use __tablename__ and some special directive, plus prepare(). Ok that other way works, but if you want to have your Engine later, type less (who doesn't ?) now you can do it *THIS* way ! great. I can guarantee you users are already completely confused by the use case - my Engine isn't there yet ? I thought I make the Engine at the top of the module, why wouldn't I have it ? Do I need to use this pattern or not ? What if I need x, y, z, q, p, r that isn't supported here ? I can try to find you a big long email from a few months ago where someone was already totally confused about the Session docs, describing that you can say sessionmaker.configure(engine) instead of Session(bind=engine) - he was *totally* mystified by that whole thing and the purpose. Very, very hard to describe convenience features, because they apply to certain use cases that most users don't have, and aren't sure they have when they first read the docs. Usage recipes make it a *ton* more clear that these are specific applications for specific problems. This new way doesn't let me customize the Table as http://www.sqlalchemy.org/docs/core/schema.html#overriding-reflected-columns talks about. This new way doesn't let me use other forms of __mapper_cls__ unless I fight with it, read its source code, etc. to get my way. Im confused should I use the "less typing" way or not? Also, a lot of apps that use reflection *can't* use this method - they have hundreds of tables and reflection is too slow. For them, we often advise reflect everything and pickle it into a serialized file, then upon app startup use that pickled file. Or use an autogen tool that derives from reflection. There's *lots* of ways to use reflection and hardcoding just one recipe in the core, just isn't appropriate at this point. Once a recipe becomes a feature, it becomes opaque. You then have to describe every aspect of the feature in documentation, put tons of hooks and calls in order to make it customizable, document all those hooks and calls, and at the end they have to end up reading the source code anyway to make it do something. The recipe means, you read and understand the source code *first*, and it doesn't need *any* special hooks because it's your code, you can customize it as you see fit (such as, to pull from your pickled file of tables instead). This again is why the philosophy is - SQLAlchemy is building blocks. You must be prepared to provide a foundation for non-trivial applications, and you must understand how the essential components function. If you want everything SQLA can offer, you'll need to think of yourself as a software developer, not a button-pushing monkey, basically. >> In particular, the recipe would need modifications if it were being >> integrated with other __mapper_cls__ types of recipes, > > Is there a list of these anywhere? (other than ones about to be superceded) there is not a list of __mapper_cls__ usage patterns any more than the Python.org documentation for the "base64" library has a list of all programs on pypi that use it, or a list of all building architectures that can be built using the assistance of a particular powersaw. __mapper_cls__ is an open ended component and I couldn't anticipate its possible uses. -- You received this message because you are subscribed to the Google Groups "sqlalchemy" group. To post to this group, send email to sqlalchemy@googlegroups.com. To unsubscribe from this group, send email to sqlalchemy+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en.