On Wed, Jul 13, 2016 at 8:03 AM, Niall <[email protected]> wrote: > Thanks for taking the time to respond. If I'm understanding what you're both > saying then the best approach may be to abandon using my customized db > wrapper and go back to using standard sqlalchemy. Since i have not really > started the reporting app yet, that's certainly doable. One of the reasons I > was opting for the custom solution was that it would give me a separate > place to put all the packaging of the data to be returned to the web app. > I'm dealing with complex data where I will normally need to touch 5 to 8 > tables to put all the pieces needed together in a query. My db structure is > granular. Instead of using things like Oracle stored procs and/or complex > views, which would anchor me in future to Oracle, I want to keep that logic > in the application, outside the database. I originally wrote the db load > application using sqlite on a Windows machine and then ported it to Oracle > on Linux, simply by re-writing the db wrapper. I'd like to continue in that > vein so that, should the company decide to move to another DB in the future, > it won't be an issue for my application.
If the ability to switch database types is more important to you than your Oracle code, then rewriting it in SQLAlchemy would be a good choice. If you're ever going to do it, you might as well do it now when you're overhauling your application anyway. But as a speaker at a PostgreSQL conference said, it's also worth taking advantage of your database's unique features, because if you use it in the least-common-denominator fashion you're not getting the most out of it. Which option you choose -- a database-neutral approach or a database-specific approach -- depends on the application. In one application I use PostgreSQL and have started using its unique types and full-text search and may use PostGIS. Another application has to work both as a website and a desktop application (the wxPython wrapper spwans a Pylons application and an embedded browser that uses it), so we initially designed it for both SQLite (desktop) and PostgreSQL (webserver). But at one point I got foreign key errors from PostgreSQL because it's stricter than SQLite, and rather than unravel them we just went with SQLite exclusively because it's performing fine on the webserver. > One other thing occurs to me:- Since Pyramid has all this routing > infrastructure built in, would another solution possibly be to build a > separate app which would service database requests and create a layer > So > now, assuming I go with pure > sqlAlchemy, is there a way I can deploy a python class between my web app's > view callables and the database to house the functionality I was going to > put in my custom wrapper? > As I said before, at this point I'm simply trying to decide the route to > take, not the actual detailed specifics of the solution. > (where > I could put my custom data packaging)? My reporting app could then route db > requests using urls to this separate database servicing app? My current structure is to have small view callables that handle the input validation and template variables and Pyramid-specific stuff, and a separate library tree for high-level queries and other logic that's not closely tied to Pyramid our the output format. That way my business logic is separate from both the views, the models, the templates, and Pyramid, so if I wanted to use it outside the Pyramid application or port it to another framework it would be clear which code would be relatively easy and which difficult. Sometimes I allow a little Pyramid into the library modules, such as the request when I need a lot of things out of it or I need to generate URLs, or the HTTP exceptions because it's silly to make a custom exception just to catch it and raise an HTTPException (and unit tests can deal with HTTP exceptions just as easily as any other exception), and 'pyramid.compat' for Python 2/3 compatible stuff. That would give you an applcation with view modules calling library modules. You can go a step further with 'pyramid_services', where you register service classes and then ask for them, but when I tried it it was overkill. It has a niche if you might sometimes want to use an alternate interpretation, then you can ask Pyramid, "Give me an object that does X (an interface)". But if you have only one implementation and no likelyhood of a second one, why not just import it directly? I have actually taken a step in the opposite direction and gone to function-based views and library functions, based on a talk at PyCon that said that functions and modules are better organization for code than classes, and more readable for future maintainers. So Iried it in a Pyramid app and it is pretty readable: you don't have to look closely for subtle 'self' references and inherited dependencies. The talk argued that classes are for data, not code, and if you have a complex set of state data then put it in an object and pass it between your functions. I don't go as far as that, and passing a state object as the first argument reminds me of the horrors of C. And it doesn't work for some things; for instance, I have a class to do model field updating. You initialize it with a model and call a method to update a field by name. It checks whether the value has changed and if so, updates the model attribute and adds it to a set of field names. Then at the end I have a set of which fields have changed, which I can put in an audit record. You can't reduce that class to functions without having to carry the set of changed fields around, which is excessively verbose. So that kind of thing I keep a class. Another approach would be a separate data-server application, so one application would be calling another, perhaps as an HTTP service. That may be useful in specialized cases where you really want to keep the data code in a separate process, either for some structural reason or to serve multilingual clients. But as a general pattern for a Pyramid application it sounds like more trouble than it's worth. When you get to the integration test section in the Pyramid manual it says that it's often better to create a unit test that sets up a minimal Configurator rather than loading the entire application if you don't need it. It's that kind of thing. If what you immediately need is a logic function, it's better to call that directly than to wrap it in a view which then has to parse the post params and make some kind of response or renderable dict. But that scales out too: it's better to call a view callable than to shoehorn your request into HTTP, which is what you'd do if you have one website call another. Sometimes that's worthwhile, as in the aforementioned common server for multilingual clients. But it's a lot of overhead if you don't have to. And if you have an extensive Javascript front end, then maybe your web application reduces down to zero, and the Javascript code can just call the data server directly. That's how GMail works. -- Mike Orr <[email protected]> -- You received this message because you are subscribed to the Google Groups "pylons-discuss" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. To view this discussion on the web visit https://groups.google.com/d/msgid/pylons-discuss/CAH9f%3DuqyzAfmcnhqT_8B3%3Dun8OjC7qhBwLqegfzR5p07FPPNcg%40mail.gmail.com. For more options, visit https://groups.google.com/d/optout.
