after_insert mapper event: can't populate target.BACKREF.attr

93 views
Skip to first unread message

sector119

unread,
Nov 8, 2011, 4:34:24 PM11/8/11
to sqlal...@googlegroups.com
Hello.

Why comments_after_insert_listener return None for target.report - backref for TripReport.comments?

class TripReportComment(Base):
    __tablename__ = 'trip_report_comments'

    id = Column(Integer, primary_key=True)
    content = Column(UnicodeText, nullable=False)
    report_id = Column(Integer, ForeignKey('trip_reports.id'), nullable=False)

def comments_after_insert_listener(mapper, connection, target):
    print target.report

event.listen(TripReportComment, 'after_insert', comments_after_insert_listener)

class TripReport(Base):
    __tablename__ = 'trip_reports'

    id = Column(Integer, primary_key=True)
    ...
    comments = relationship('TripReportComment', backref='report', cascade='all, delete-orphan', order_by='TripReportComment.id')


Michael Bayer

unread,
Nov 8, 2011, 5:33:36 PM11/8/11
to sqlal...@googlegroups.com
On Nov 8, 2011, at 1:34 PM, sector119 wrote:

Hello.

Why comments_after_insert_listener return None for target.report - backref for TripReport.comments?

when you do...what exactly?  this is just a mapping, looks fine.    Can you provide a fully working example please ?






class TripReportComment(Base):
    __tablename__ = 'trip_report_comments'

    id = Column(Integer, primary_key=True)
    content = Column(UnicodeText, nullable=False)
    report_id = Column(Integer, ForeignKey('trip_reports.id'), nullable=False)

def comments_after_insert_listener(mapper, connection, target):
    print target.report

event.listen(TripReportComment, 'after_insert', comments_after_insert_listener)

class TripReport(Base):
    __tablename__ = 'trip_reports'

    id = Column(Integer, primary_key=True)
    ...
    comments = relationship('TripReportComment', backref='report', cascade='all, delete-orphan', order_by='TripReportComment.id')



--
You received this message because you are subscribed to the Google Groups "sqlalchemy" group.
To view this discussion on the web visit https://groups.google.com/d/msg/sqlalchemy/-/xlOoyFWOAZUJ.
To post to this group, send email to sqlal...@googlegroups.com.
To unsubscribe from this group, send email to sqlalchemy+...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en.

sector119

unread,
Nov 9, 2011, 3:23:48 AM11/9/11
to sqlal...@googlegroups.com
# test_event.py

from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base

from sqlalchemy import Column, ForeignKey
from sqlalchemy import Integer, UnicodeText
from sqlalchemy import event

from sqlalchemy.orm import relationship

engine = create_engine('postgresql+psycopg2://USER:PASS...@127.0.0.1:5432/test', echo=True)

Session = sessionmaker()
Base = declarative_base()

Session.configure(bind=engine)
Base.metadata.bind = engine

class Comment(Base):
    __tablename__ = 'comment'
   
    id = Column(Integer, primary_key=True)
    content = Column(UnicodeText, nullable=False)
    report_id = Column(Integer, ForeignKey('report.id'), nullable=False)

def comment_after_insert_listener(mapper, connection, target):
    target.report.comments_count += 1

event.listen(Comment, 'after_insert', comment_after_insert_listener)

class Report(Base):
    __tablename__ = 'report'
   
    id = Column(Integer, primary_key=True)
    content = Column(UnicodeText, nullable=False)
    comments_count = Column(Integer, server_default='0', nullable=False)
   
    comments = relationship('Comment', backref='report', cascade='all, delete-orphan', order_by='Comment.id')

Base.metadata.create_all(engine)

session = Session()

report = Report(content=u'test report')
session.add(report)
session.flush()
session.commit()

comment = Comment(content=u'test comment', report_id=1)
session.add(comment)
session.flush()
session.commit()                                                                                                                             


% /home/eps/tourclub/bin/python test_event.py
2011-11-09 10:19:38,970 INFO sqlalchemy.engine.base.Engine select version()
2011-11-09 10:19:38,970 INFO sqlalchemy.engine.base.Engine {}
2011-11-09 10:19:38,972 INFO sqlalchemy.engine.base.Engine select current_schema()
2011-11-09 10:19:38,972 INFO sqlalchemy.engine.base.Engine {}
2011-11-09 10:19:38,974 INFO sqlalchemy.engine.base.Engine select relname from pg_class c join pg_namespace n on n.oid=c.relnamespace where n.nspname=current_schema() and relname=%(name)s
2011-11-09 10:19:38,974 INFO sqlalchemy.engine.base.Engine {'name': u'report'}
2011-11-09 10:19:38,976 INFO sqlalchemy.engine.base.Engine select relname from pg_class c join pg_namespace n on n.oid=c.relnamespace where n.nspname=current_schema() and relname=%(name)s
2011-11-09 10:19:38,976 INFO sqlalchemy.engine.base.Engine {'name': u'comment'}
2011-11-09 10:19:38,978 INFO sqlalchemy.engine.base.Engine
CREATE TABLE report (
        id SERIAL NOT NULL,
        content TEXT NOT NULL,
        comments_count INTEGER DEFAULT '0' NOT NULL,
        PRIMARY KEY (id)
  
  
2011-11-09 10:19:38,978 INFO sqlalchemy.engine.base.Engine {}
2011-11-09 10:19:39,041 INFO sqlalchemy.engine.base.Engine COMMIT
2011-11-09 10:19:39,051 INFO sqlalchemy.engine.base.Engine
CREATE TABLE comment (
        id SERIAL NOT NULL,
        content TEXT NOT NULL,
        report_id INTEGER NOT NULL,
        PRIMARY KEY (id),
        FOREIGN KEY(report_id) REFERENCES report (id)
  
  
2011-11-09 10:19:39,051 INFO sqlalchemy.engine.base.Engine {}
2011-11-09 10:19:39,134 INFO sqlalchemy.engine.base.Engine COMMIT
2011-11-09 10:19:39,145 INFO sqlalchemy.engine.base.Engine BEGIN (implicit)
2011-11-09 10:19:39,146 INFO sqlalchemy.engine.base.Engine INSERT INTO report (content) VALUES (%(content)s) RETURNING report.id
2011-11-09 10:19:39,146 INFO sqlalchemy.engine.base.Engine {'content': u'test report'}
2011-11-09 10:19:39,147 INFO sqlalchemy.engine.base.Engine COMMIT
2011-11-09 10:19:39,151 INFO sqlalchemy.engine.base.Engine BEGIN (implicit)
2011-11-09 10:19:39,152 INFO sqlalchemy.engine.base.Engine INSERT INTO comment (content, report_id) VALUES (%(content)s, %(report_id)s) RETURNING comment.id
2011-11-09 10:19:39,152 INFO sqlalchemy.engine.base.Engine {'content': u'test comment', 'report_id': 1}
2011-11-09 10:19:39,154 INFO sqlalchemy.engine.base.Engine ROLLBACK
Traceback (most recent call last):
  File "test_event.py", line 54, in <module>
    session.flush()
  File "/home/eps/devel/tourclub/sqlalchemy/lib/sqlalchemy/orm/session.py", line 1547, in flush
    self._flush(objects)
  File "/home/eps/devel/tourclub/sqlalchemy/lib/sqlalchemy/orm/session.py", line 1616, in _flush
    flush_context.execute()
  File "/home/eps/devel/tourclub/sqlalchemy/lib/sqlalchemy/orm/unitofwork.py", line 328, in execute
    rec.execute(self)
  File "/home/eps/devel/tourclub/sqlalchemy/lib/sqlalchemy/orm/unitofwork.py", line 472, in execute
    uow
  File "/home/eps/devel/tourclub/sqlalchemy/lib/sqlalchemy/orm/mapper.py", line 2270, in _save_obj
    mapper.dispatch.after_insert(mapper, connection, state)
  File "/home/eps/devel/tourclub/sqlalchemy/lib/sqlalchemy/event.py", line 274, in __call__
    fn(*args, **kw)
  File "/home/eps/devel/tourclub/sqlalchemy/lib/sqlalchemy/orm/events.py", line 360, in wrap
    wrapped_fn(*arg, **kw)
  File "test_event.py", line 29, in comment_after_insert_listener
    target.report.comments_count += 1
AttributeError: 'NoneType' object has no attribute 'comments_count'

sector119

unread,
Nov 9, 2011, 7:16:09 AM11/9/11
to sqlal...@googlegroups.com
this works without any error, comment_after_insert_listener() prints that target.report.comments_count = 1, but this value isn't commited...

Can't get why prev testcase fails, this works, but target.report.comments_count  value isn't saved :/


def comment_after_insert_listener(mapper, connection, target):
    target.report.comments_count = target.report.comments_count + 1
    print target.report.comments_count

event.listen(Comment, 'after_insert', comment_after_insert_listener)
                                                                                                                                                           
session = Session()                                                                                                                                          
report = session.query(Report).get(1)
comment = Comment(content=u'test comment', report=report)
session.add(comment)
session.commit()

Reply all
Reply to author
Forward
0 new messages