Thanks for the great test case and this would be appropriate to be posted as a bug, since it is a complete description.

So, the reason the primary key is not included right now is because primary keys are populated in many different ways on the object, meaning if your code relies upon refresh_flush(), it will break if you switch to another database, or use an old version of Postgresql that doesn't support RETURNING, or the table/dialect is set up to no longer use RETURNING, etc. The primary key is not actually populated at that point the way the other defaults are (it was already populated previously, so I guess to the event consumer, it doesn't make that much difference).

Looking at where refresh_flush is called, there is still inconsistency for other kinds of defaults too; if you use eager_defaults with a MySQL database and server-side defaults it looks like you'd get called in the ordinary refresh() event anyway (that is, if you try to eager_defaults against a server_default="0", a Postgresql DB will call refresh_flush, a MySQL DB will call refresh()).

Still, a primary key that's an autoincrement will never come back for MySQL within either of these events - there's no RETURNING for MySQL (and others).

refresh_flush() is very new and not widely used and it is likely harmless to just add what we have here (not to mention document it either way). But for any change I'd first ask, what are you trying to do? The primary keys are excluded from "refresh" because they are not usually a part of that concept, primary keys are "first class" and always get pulled no matter what, you can grab them in after_insert(), for example.





On 07/29/2016 04:25 AM, Lenar Imamutdinov wrote:
Hello!

Looks like the refresh_flush event is not triggered when the only field
to update after flush is the primary key fed from RETURNING clause.
However it should, as far as I understand what is mentioned in the
documentation.

Environment: SQLAlchemy 1.0.14, PostgreSQL 9.5, Python 3.4

Here is how to reproduce this problem:

    from sqlalchemy.ext.declarative import declarative_base
    from sqlalchemy import Column, Integer
    from sqlalchemy import create_engine
    from sqlalchemy.orm import Session
    from sqlalchemy import event

    Base = declarative_base()

    def receive_refresh_flush(target, context, attrs):
        print('refresh_flush received')

    class Test(Base):
        __tablename__ = 'refresh_flush_test'
        id = Column(Integer, primary_key=True)
        # uncomment the field below to receive the event
        # dummy = Column(Integer, default=0)

    engine = create_engine('postgresql://test:test@localhost:5432/test')
    Base.metadata.create_all(engine)
    session = Session(engine)

    event.listen(Test, 'refresh_flush', receive_refresh_flush)

    obj = Test()
    session.add(obj)
    session.commit()

--
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
<mailto:sqlalchemy+unsubscr...@googlegroups.com>.
To post to this group, send email to sqlalchemy@googlegroups.com
<mailto:sqlalchemy@googlegroups.com>.
Visit this group at https://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.

--
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 https://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.

Reply via email to