Changing the declarative base of a class and re-mapping

40 views
Skip to first unread message

Ahmed

unread,
Jul 13, 2013, 1:48:47 AM7/13/13
to sqlal...@googlegroups.com
Hello all,

I have the following scenario:
I have 5 or 6 related sqlalchemy declarative models sitting in a pyramid app. This occurs in the context of extending a pyramid application, where I import/config.scan() these selected models from another pyramid app into a new app. The thing is that these models have the original app's declarative base and I need them to work with the new app's declarative base.

So I tried to change their declarative base upon importing. (also with giving a new name to avoid possible name collisions)
This was my approach:
newmodel = type(newmodelname, (newdeclarativebase, oldmodel), {})

which worked out pretty well!!! except for one nuisance, which is that already instrumented relationships are still bound to the old models instead of the new ones.

class OldParentModel(oldbase):
    rel = relationship("OldChildModel")

>> new = query(NewParentModel).first()
>> new.rel
      [<oldapp.models.OldChildModel at 0xb1cbfac>]

I wished that they are linked to NewChildModel instead.

so is there a way to avoid this problem or at least remap the already mapped relationships to the new models?
Or perhaps a whole different approach to dealing with this (without actually redefining the whole classes again in the new app)?

Cheers,
Ahmed

Ahmed

unread,
Jul 13, 2013, 1:28:39 PM7/13/13
to sqlal...@googlegroups.com
It seems that I have found a solution. After digging in sqlalchemy code, it seems that the _configure_property mapper function would do the trick.

so ...

newprop = RelationshipProperty(newtargetmodel, **rel_kwargs)
newparentmodel.__mapper__._configure_property(oldprop.key, newprop)

so what I did above was to construct a new RelationshipProperty (copying all the key word arguments from the old property) and then configure it onto the new model (which inherits from the old one).

Before this step I also disposed of the old model mapper using mapper.dispose() and remapped using mapper() but without specifying the relationships in the mapper 'properties', this gave me the same classes with only the columns and without the relationship properties, which I then attached later using the _configure_property manually as above.

Cheers,
Ahmed

Michael Bayer

unread,
Jul 13, 2013, 1:57:27 PM7/13/13
to sqlal...@googlegroups.com

On Jul 13, 2013, at 1:48 AM, Ahmed <ahmed...@gmail.com> wrote:

> Hello all,
>
> I have the following scenario:
> I have 5 or 6 related sqlalchemy declarative models sitting in a pyramid app. This occurs in the context of extending a pyramid application, where I import/config.scan() these selected models from another pyramid app into a new app. The thing is that these models have the original app's declarative base and I need them to work with the new app's declarative base.

there's no reason you can't have multiple declarative bases, and those classes can still interact with each other. All you lose is that the two bases by default use a different MetaData registry and a different registry of string class names; but if these two bases are from different apps anyway, there should be few to no linkages between them. The use case of merging two apps together at runtime and swapping out bases seems very exotic.
Reply all
Reply to author
Forward
0 new messages