Yup, I understood your question :) Let me see if I can be a little more
specific.
Even with inheritance and polymorphism, you still have two tables
(entity and child) in the database. If you update just the value in the
Child instance (which exists just in the child table), the entity table
has nothing to do with it. If you "touch" only your Child instance
attribute and none from the Parent instance, only its value (child) will
be updated.
You can check if your parent instance is dirty after changing a value
from child, it will probably return False:
*obj.value = "foobar"**
**p = session.query(Parent).filter(Parent.id == obj.id).one()**
**p in session.dirty # should return False. If returns True, then I
think it is a bug**
**obj in session.dirty # shoud return True. go figure ...*
*IF* you want this to work without much effort, you should use
updated_at in Child (which I agree if you think "you must be joking" or
"you really must be joking", lol). If don't, polymorphism will not do
that "automagically", at least IMHO. You can also check if there's a way
to make the whole object dirty :)
Indeed it's a tricky situation, SA is expected by us to do this (and I
think it may be our fault), but if it doesn't, the logic is also plausible.
I'll dig around the code too see what can be done.
Cheers,
Richard.
On 11/08/2013 09:34 AM, Bertrand Mathieu wrote:
Hello,
Thank you for your answer, but unless I miss something in your answer
my problem has to do with polymorphic inheritance, it's not about
relationship between 2 models. By inheritance "updated_at" is an
attribute of any Child instance ( Child().updated_at exists).
I realize I didn't explained the example I joined:
(I also realize that Parent.__tablename__ is named 'entity', don't be
confused)
class definitions:
class Parent(Base):
__tablename__ = 'entity'
__mapper_args__ = {'polymorphic_on': 'entity_type',
'with_polymorphic': '*',
}
entity_type = Column('entity_type', String(1000), nullable=True)
id = Column('id', Integer(), primary_key=True)
name = Column('name', String(1000), default=u'')
updated_at = Column(sa.DateTime,
default=datetime.utcnow,
onupdate=datetime.utcnow)
class Child(Parent):
__tablename__ = 'child'
__mapper_args__ = {'polymorphic_identity': 'Child'}
id = Column(Integer,
ForeignKey('entity.id', name='fk_inherited_entity_id'),
primary_key=True)
text = Column('text', String(1000), default=u'')
When run() is executed:
obj = Child()
session.add(obj)
session.commit()
SQL emitted:
INSERT INTO entity (entity_type, name, updated_at) VALUES (?, ?, ?)
('Child', u'', '2013-11-08 10:27:18.886677')
INSERT INTO child (id, text) VALUES (?, ?)
(1, u'')
COMMIT
I change only one of Child's attributes:
obj.text = 'some text'
session.commit()
SQL:
UPDATE child SET text=? WHERE child.id = ?
('some text', 1)
COMMIT
-> updated_at on table entity is not changed, so obj.updated_at is
left untouched: don't want that.
But if I also change "name" (defined on Parent)
obj.name = u'test'
obj.text = 'some text'
session.commit()
SQL:
UPDATE entity SET name=?, updated_at=? WHERE entity.id = ?
(u'test', '2013-11-08 10:27:18.891200', 1)
UPDATE child SET text=? WHERE child.id = ?
('some text', 1)
COMMIT
obj.updated_at is changed.
Le vendredi 8 novembre 2013 12:09:13 UTC+1, Richard Gerd Kuesters a
écrit :
I think the code is correct and is behaving correctly also --
since you update just the child, the parent isn't touched (it
already has data and was not changed in this session).
What you could do is add an update event to your Child object:
*def update_child(mapper, connection, target):**
** # target is your child updated**
** target.parent.updated_at = datetime.datetime.now() #
assuming you have mapped parent as a backref object or something**
** object_session(target).commit()**
**
**event.listen(Child, 'after_update', update_child)**
*
If you want the same after an insert or delete, you should declare
other events[1] as well. I think there might be other ways to do
that, but I usually use events for its flexibility.
You can also use before_update to use the same session.commit()
[1] http://docs.sqlalchemy.org/en/rel_0_8/orm/events.html
<http://docs.sqlalchemy.org/en/rel_0_8/orm/events.html>
Best regards,
Richard.
On 11/08/2013 08:38 AM, Bertrand Mathieu wrote:
Hi,
I have a set up class inheritance using joined table inheritance.
I'm using sqlalchemy 0.8.2.
The Parent class has a DateTime attribute "updated_at", with
onupdate=datetime.utcnow.
If I update only one of the Child's attributes, only "child"
table is updated, parent.updated_at is not changed. If I change
one of the Parent's attributes, then updated_at is updated as
expected.
Here's my questions:
1) Am I missing something in my setup? is it normal or is it a bug?
2) If this is normal, what is the right way to tell session that
"parent.updated_at" should be modified too?
Regards,
--
Bertrand
--
You received this message because you are subscribed to the
Google Groups "sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it,
send an email to sqlalchemy+...@googlegroups.com <javascript:>.
To post to this group, send email to sqlal...@googlegroups.com
<javascript:>.
Visit this group at http://groups.google.com/group/sqlalchemy
<http://groups.google.com/group/sqlalchemy>.
For more options, visit https://groups.google.com/groups/opt_out
<https://groups.google.com/groups/opt_out>.
--
You received this message because you are subscribed to the Google
Groups "sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, send
an email to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/groups/opt_out.
--
You received this message because you are subscribed to the Google Groups
"sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/groups/opt_out.