Closed
Description
Migrated issue, originally created by Anonymous
Hi everyone!
I'm writing my own ORM based on SQLAlchemy and I need to subclass sqlalchemy.schema.Column. The only issue I have is with copy() function. Now I have to copy-paste it to my code and fix it there.
I wanted to use something like:
class MyProperty(sqlalchemy.Column):
...
def copy(self, **kw):
c = super(MyProperty, self).copy(**kw)
c.foo = self.foo
...
return c
But in this case a copy will be of type sqlalchemy.Column instead of MyProperty. Is it possible to rewrite sqlalchemy.Column.copy() like this:
def copy(self, **kw):
...
c = type(self)(
name=self.name,
...
doc=self.doc,
*args
)
c.dispatch._update(self.dispatch)
return c
Can this be done in 0.7.x?
Metadata
Metadata
Assignees
Type
Projects
Relationships
Development
No branches or pull requests
Activity
sqlalchemy-bot commentedon Sep 23, 2011
Michael Bayer (@zzzeek) wrote:
what's your use case for subclassing Column ? I'd prefer to give you another way to do what you need.
sqlalchemy-bot commentedon Sep 23, 2011
Changes by Michael Bayer (@zzzeek):
sqlalchemy-bot commentedon Sep 23, 2011
Anonymous wrote:
I'm creating network ORM and subclass Column to introduce additional introspection to it (7 more attributes). E.g.: is it hidden (from prospective of clients), more information on foreign keys and so on
sqlalchemy-bot commentedon Sep 23, 2011
Michael Bayer (@zzzeek) wrote:
So what I can do for you here is in e4c0459, where an existing attribute
_constructor
is used to create the copy - this method defaults toself.__class__
, equivalent totype(self)
without the function call._constructor
is already used in the_make_proxy()
function, which is similar tocopy()
except it is a much more important method as it is used very frequently within expression transformation -copy()
is only used by thetometadata()
utility system. it was likely an oversight that_constructor
was not used here already. The unit test added mimics exactly the pattern you're asking for here.That said, subclassing
Column
is a little dangerous. I would encourage you to at least store your extra state within the.info
dictionary ofColumn
, which is provided for end-user storage of extra attributes. If.info
were good enough for you without the need for additional methods/accessors, you could skip the need to subclassColumn
and just use a function that puts what you want in.info
.It's also worth noting that the SQLAlchemy ORM adds lots of ORM-specific functionality column-bound attributes, but doesn't need to subclass
Column
itself, since it uses a proxy pattern viaInstrumentedAttribute
- which itself implementsPropComparator
to provide all of the column operators, and proxies those requests down to an actualColumn
. This pattern, that of composition/proxying rather than direct subclassing, allows a lot more trickery to go on at the ORM layer without being destablized by changes in the schema package.Anyway that's my advice on that, the change committed should resolve the specific issue you're having with subclassing - good luck !
sqlalchemy-bot commentedon Sep 23, 2011
Changes by Michael Bayer (@zzzeek):
sqlalchemy-bot commentedon Sep 23, 2011
Michael Bayer (@zzzeek) wrote:
Oh I'd also note, you can subclass
_constructor()
itself too. That was the original idea behind that method - that subclassing_constructor()
would eliminate the need to dig intocopy()
and particularly the_make_proxy()
method:sqlalchemy-bot commentedon Sep 24, 2011
Anonymous wrote:
Thank you, that should solve my problems. Also thank you for your notes!
Waiting for 0.7.3...
sqlalchemy-bot commentedon Nov 5, 2011
Anonymous wrote:
Please note that your example is wrong, the correct one seems to be: