I take this as opportunity to compliment the DAL. I have never seen clever way to manipulate data in a relational database. I am actually addicted to the way it works. I wish could work with web2py as my primary job.
2012/5/5 Massimo Di Pierro <[email protected]>: > On Saturday, 5 May 2012 10:23:34 UTC-5, Tiago Almeida wrote: >> >> Hi, >> The issue about dal/orm, like Anthony said, there are tradeoffs to >> consider. In my opinion you loose too much not having an orm to gain very >> little with the dal. Let me continue my example. >> In the Deparment/Teacher hypothetical model, you also have assignment of >> Teachers to Departments. This assignment is very simple (for the sake of >> brevity) and has the start/end dates of the assignment and the function >> (just a string) of the Teacher in that Department. >> You now want, Given the ID of a department list all the assignments of all >> teachers along with their functions in a cool graphical timeline fashion. >> It's not about how you get the data. It's about the effort you have >> implementing this req. and how you organize your code. Do you? >> a) write your .selects() in the view function >> b) write a historical_assignments(dep_id) function somewhere that hides >> the DAL and call it from the view >> c) write a computed field on the department model >> d) write a method historical_assignments() on the class Department >> >> To me, the d) option is by far the most elegant. I would have had the >> Department class created anyway, so it's a matter of sticking a method in >> there. If I am working with an ORM, by defining the classes, I automagically >> get the tables defined. Without it, I have to repeat myself, redefining the >> fields and the fields in the tables and their types, etc. etc. in the >> persistance layer. >> What if I didn't define those classes? Then I couldn't contain these kinds >> of business related operations into a single application layer and they >> would leak everywhere, for instance in to the views, being much harder to >> maintain. > > > this is somewhat a religious matter. We do not like to pollute the namespace > with one class per table. We do not even usually do Department = > db.define_table(...). We just expose db and access department via > db.department. Given this preference: > > db.departement.historical_assignments = Field.Lazy(lambda departement, date: > db(db.teacher.departement)(db.teacher.asdate<date).select()) > > seems simpler and clear than to define a class and a method. It does not > pollute the namespace. In fact web2py does allow to create a VirtualField > class and map that into table, so that records have fields corresponding to > methods. We consider it a legacy feature because users prefer the new > syntax. > Yet this is kind of a religious issue. > >> Regarding the higher vs different abstraction. A "perfect" persistence >> layer (if there is such a thing) allows one to actually forget that you have >> a DB system. I honestly don't care, from the biz point of view, if things >> are stored in tables in a DB, xml files or sent via the wire to China. I >> only care that I create my Departments, .save() them and get them later as >> they were saved .get(id=dep_id). > > > We do not want to "forget" that we have a DB system. One can only forget > when one builds simple queries. Ifone can only do simple queries than one > starts to think a relational database is not good enough. We want to make > sure .select() maps in an SQL SELECT, .insert() into SQL INSERT, etc. We do > not want to hide database access which can cause performance issues. This is > a significative difference. We do no need .save() and .get() because they > are kind of like .insert() and .select() but the mapping is not always as > clear. Moreover is not very Object Oriented either. > >> >> Do you lose anything with this abstraction? Yes, of course. If you hide >> that it's a DB you lose, for instance, DB triggers. It's the normal tradeoff >> in any abstraction. If you use TCP, you get delivery guarantees and peace of >> mind regarding all the dropped/corrupted packets nonsense while loosing, >> say, realtime guarantees. Should we stop using TCP because we loose this >> 'realtimeness'? Of course not. >> Are there things that you can do with an orm that you can not with adal? >> No, it's quite the opposite. The dal exposes more details therefore allows >> you to do more. However, by exposing all these details, you get a tool that >> is harder to use (in the sense that you have to repeat yourself) for all the >> other scenarios where you don't need such details. Python is used because no >> one wants to deal with the nonsense of lower level languanges that arise >> from exposing too many details (manual memory management, target machine >> dependency, etc....). >> Lastly, If I am working with an orm and need to implement a really complex >> query, nothing stops me from going deeper and use the dal or even writing >> SQL. > > > This is what we do not like. The goal of the DAL is to try avoid this as > much as possible, although it does not prevent it. > >> >>> >>> look at >>> the Django ORM Tutorial example: >>> >>> Poll.objects.filter(question__startswith='What') >>> >>> In web2Py DAL it would use more standard python methods: >>> >>> db( db.Poll.question.startswith("what") ).select() >> >> I've never said that Django's orm is perfect. That "__operator" thing >> could be done in a different way. Anyway I accept that minor annoyance >> because it saves me time overall. > > > I see this in a different light. Web2py supported left joins, aggregates, > and nested selects 2 years before Django did. While they added those > features over time, we added so many other features (list types, native GAE > support, geospatial APIs for postgres, mongodb support, teradata support, > imap-dal support, expressions, lazy virtual fields, full auditing in all > database tables, multiple database support, semi-natural-language query > parsing, etc.) that it is pointless to even compare them today, and we > managed to remain backward compatible. > > The DAL expressions are consistently shorter then the equivalent Django and > SQLAlchemy ones (some example here > http://www.web2py.com/AlterEgo/default/show/150 and I would love to see a > counter example) and support more features than Django does (in the sense we > can use the DAL to generate more SQL statements than the Django ORM can). > > Web2py falls short of SQLAlchemy for support of legacy tables with arbitrary > primary keys (but we have been getting better) and for lack of the concept > of DB session (because we never needed that). > > Just for fun two years ago, I implemented a Django-compatible ORM for > web2py: > http://www.web2py.com/AlterEgo/default/show/189 > Nobody used it so it died but it would be trivial to improve it to add a > mapping between arbitrary methods and virtual fields. > > Since you are building your own ORM, instead of starting from scratch, you > may want to look into proving that and still take advantage of the DAL > goodies underneath. > > Anyway, please understand we value your comments as we can learn from them. > > Massimo > -- Carlos J. Costa Cientista da Computação Esp. Gestão em Telecom EL MELECH NEEMAN! אָמֵן

