On Jun 25, 2011, at 10:59 PM, Arthur Kopatsy wrote:

> Hi,
> 
> I have seen a few related questions but never a clear answer. I have a
> set of core models defined using a declarative form. These models are
> used by multiple applications.
> 
> In each application we however want to extend this model class with
> helper methods. Since these methods are application specific, they
> cannot be define in the model itself.
> 
> I have tries multiple ways with no success and all pretty gross in my
> opinion:
> 1. Subclass the original model, catch the SA load event and set
> __class__ to whatever I want.
> Problem: mapper was getting confused if the original model and the
> subclass had the same name.
> 2. Modify __bases__ and and my helper class to inject methods.
> Problem: it fails with model inheritance.
> 3. Monkey patch the module itself (models.MyModel = MyCustomModel).
> Problem: Mapper fails right away (class not mapped)
> 4. Monkey patching the class and add methods and attributes: best
> solution so far.
> 
> What is the recommended way? I would love to be able to subclass the
> model and tell the mapper to use that new class instead...


If these applications run in different process spaces, and if you are able to 
identify which application is running at module import time, you can achieve 
this effect through careful organization of imports:


model/__init__.py
model/some_model.py

model/app1/__init__.py
model/app1/helpers.py

model/app2/__init__.py
model/app2/helpers.py

in model/__init__.py:

if app == 'app1':
    from model.app1 import helpers
elif app == 'app2':
    from model.app2 import helpers

in model/some_model.py:

from model import helpers
class SomeWidget(Base, helpers.Widget):
    #  declarations

class SomeFoober(Base, helpers.SomeFoober):
   # declarations

This might not be too different from your "inject __bases__" approach.   That 
should also work, if you're having trouble with inheritance you need to inject 
into __bases__ only at the appropriate points, checking each target class as to 
whether or not it's already part of an inheritance hierarchy.

Another approach is to declare the model as mixins, then the individual 
applications declare the actual "mapped" models using those mixins.   This is 
basically the same idea in the opposite direction.   However that approach is 
more appropriate if the model itself also varies among applications (I have an 
app that does this).   In this case it appears the variability is just on the 
"some methods to be mixed in" side.








> 
> Thank you
> 
> Arthur
> 
> -- 
> 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.
> 

-- 
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.

Reply via email to