> Sorry, but what should do .list() ? 
> it is a query? it is pre-fetched or cached? 
>

The whole point of having an ORM, is for you to not have to worry about the 
answer to that question - it's gonna do the optimal thing it can, based on 
the circumstances in which it is called.
As I described, like 10 times already, ORMs are statefull - they have 
cache-management built-in.
The question of how these cache-management is working, and so whether or 
not you can trust it, is a long and complex question. Suffice it to say, 
that there has been more than a decade of research into this issue, so it 
is solved.
Just as example, if the list has objects in it, it will check that what it 
has is up-to-date. If it is called within the context of a transaction that 
is in progress, and it had already did a query for that beforehand within 
the same transaction, than by ACID's "C of Consistency" rule, the code 
should assume that it's cached-data is up-to-date. If between the 
previously-called query, and this call, a transaction was ended and a new 
one started, then according to ACID's "C of Consistency" rule, the code 
should not assume that the data is up-to-date, and issue a query.
ORMs like SQLA's ORM do a 'Unit-Of-Work' patterns, in which these caches 
are managed for you. Any transaction-commit invalidates the caches, so you 
can guarantee consistency across transactions.
 

> What about if I need the cities of countries where main language is 
> not Spanish, and population is above 1 millon?
>

ORMs allow you to attache filters for that, it really depends on the 
implementation, but let's think of some options, shell we?

The most straight-forward approach I would suggest, is the layered-approach 
- meaning, the ORM should use the DAL for that internally.
It should allow you to construct the filters yourself using the DAL, and 
have mechanisms to facilitate attaching of filters to these attributes.

We can go into a discussion of how it will look like in an ORM in web2py in 
each of the options - which would be the fun-part, I think - so let's see:

First, let's extend the schema and ORM example-definitions to include that:

db.define_table('Language', Field('Name', 'String'))
db.define_table('Continent', Field('Name', 'string'))
db.define_table('Country', Field('Name', 'string'), Field('Continent', 
db.Continent))
db.define_table('City', Field('Name', 'string'), Field('Country', db.Country), 
Field('Language', db.Language), Field('Population', 'Integer'))

@ORM(db.Language)
class Language:
    pass

@ORM(db.City)
class City:
    pass

@ORM(db.Country)
class Country:
    pass

@ORM(db.Continent)
class Continent:
    pass


>>> ...
>>> spanish = Language(Name='Spanish')
>>> french = Language(Name='French')
>>> france.City.Language = french
>>> ...


Then, we could devise to do any number of things:

We can build basic stuff like .isGraterThan() into the ORM classes, and do:

>>> ...
>>> [city for city in fance.City.list if \
city.Language is not spanish and city.Population.isGraterThan(1000000)]
[<City Name:Paris>]

It almost reads like plain English... Beautiful (!)

Alternatively, we could have a set of operators that we can give to a 
filter function:

>>> ...
>>> from ORM.operators import not, moreThan
>>> france.City.where(
Language=not(spanish), Population=moreThan(1000000))
[<City Name:Paris>]

Lastly, we could let the developer filter objects using the DAL indirectly:

>>> ...
>>> france.City.FilterBy(
(City.Languase != spanish) & (City.Population > 1000000))
[<City Name:Paris>]
 

> Please, note that you are mixing a declarative query syntax (DAL), 
> with an imperative one (ORM) 
>
>
No, I am LAYERING imperative-syntax "on-top" of declarative one.

>
> I would like a elegant declarative syntax similar to LINQ, but in python: 
>
> [city for db.City.ALL in db.City, db.Country if db.Country.Name == 
> 'France' and db.Country.id == db.City.country] 
>
>
My first suggestion was way more readable.
 

> Sadly, there is NO possible way to archive a pythonic list 
> comprenhension syntax that query the objects in the server side AFAIK


Not sure what you mean...
 

>
> Some libraries uses dis (python disassembler) and other internal & 
> dirty python hacks to do something similar, please, see: 
>
> http://www.aminus.net/geniusql/ 
>
> http://www.aminus.org/blogs/index.php/2008/04/22/linq-in-python?blog=2 
>
> http://www.aminus.net/geniusql/chrome/common/doc/trunk/managing.html 
>
> Note that web2py is much closer to the "pythonic expressions", but 
> without the early / late binding and other issues described there ;-) 
>
 
I will look into that.


This would require caching or storing previous queried record in 
> memory (something like a singleton), or "is" will not work as you are 
> expecting (it is for checking "identity")... 
>

Exactly! This is exactly what SQLA is already doing - I explained that 
before - it uses what it calls 'Identity Mapping' internally:
http://www.youtube.com/watch?v=woKYyhLCcnU#t=6382s<http://www.youtube.com/watch?v=woKYyhLCcnU>
** Time-coded link - watch the following 4 minutes *
 

> That could be also archived hacking "Row", but you should use == in 
> python for this kind of comparision (equality) 
>
>
Not is SQLA :) 
Web2py *could *do that too.


> For you that are creating it, but I will not understand it in a first 
> sight, so I prefer the DAL syntax that is a bit verbose but more 
> uniform 
>

There is no non-uniformity in SQLA syntax, as there are 2 layers that 
are explicitly-different. Web2py could do that too.
 

> (at least I know what I'm doing in each step, or can get a SQL book 
> and see how to "pythonize" the expression) 
>

Same as in SQLA - again, I am suggesting "augmenting" the DAL with another 
separate ORM layer - not replacing the DAL.
 

> A ORM is not more intuitive and will have a higher learning curve, and 
> no formal / logical / math justification theory  BTW 
>
> An ORM is MUCH MORE intuitive, as my examples had demonstrated, and  the 
formal/logical/math justification would still apply within the DAL layer 
that would still exist underneath.

-- 

--- 
You received this message because you are subscribed to the Google Groups 
"web2py-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to