On 01/21/2011 01:47 AM, Andrey Popp wrote:
Hello,

On Jan 21, 2011, at 1:48 AM, Juliusz Gonera wrote:

Is it considered bad practice to make DB queries in model's methods? Or is this 
the way to go?

Yes, it's a bad practice in general -- model should be persistence-agnostic.

for the record, there are lots of folks who disagree with this statement. while there are certainly cases where the extra abstractions that you detail below are useful, IMHO they're overkill for most applications, which are only intended to work w/ a single persistence engine and which gain little benefit from the added complexity.

-r

And even if you're not planning to use the same models with different storage 
options or outside of SQLAlchemy context, I still recommend you to separate 
queries and data manipulation routines in separate class -- ModelManager, 
ModelRepository, ...

The rules that I follow are:

   * If function operates on entire table (insert something into table, query 
from table or etc.) -- it should become a member or model's manager.

   * If function is a part of behavior of model (in a sense of its domain)-- it 
should become model's method.

So, I think it's worth to delegate such relationship management to model's 
manager:

   class MainModelManager(object):

       def add_some_related_object(self, main_obj, param1, param2):
           # query something
           related = SomeRelatedObject()
           main_obj.some_related_objects.append(related)

If you think, that this method would require also some participation of main 
model's inner state, you can replace 
`main_obj.some_related_objects.append(related)` with special method of 
MainModel:

    class MainModel(object):
        def add_some_related_object(self, related):
           # some business logic, which is not require database access
           main_obj.some_related_objects.append(related)

   class MainModelManager(object):

       def add_some_related_object(self, main_obj, param1, param2):
           # query something
           related = SomeRelatedObject()
           main_obj.add_some_related_objects(related)

This way you can separate business logic from persistence.

It also helps to provide better testability of you code, cause you can test 
domain logic inside `MainModel.add_some_related_object` without requiring 
existence of test SQL database.


--
You received this message because you are subscribed to the Google Groups 
"pylons-discuss" group.
To post to this group, send email to pylons-discuss@googlegroups.com.
To unsubscribe from this group, send email to 
pylons-discuss+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/pylons-discuss?hl=en.

Reply via email to