On Fri, Jan 24, 2014 at 4:22 PM, Simon King <si...@simonking.org.uk> wrote: > Hi again, > > While testing the complicated relationship from the other thread, I > noticed that I was generating a lot of queries that I couldn't > immediately explain. After a bit of digging, it turned out that it was > due to my use of code based on the "versioned objects" example at > http://docs.sqlalchemy.org/en/rel_0_9/_modules/examples/versioned_history/history_meta.html. > > In the test script below we have 3 classes. Users belong to Companies, > and Companies reference a single Terms row. In the example, only the > Company class is versioned. > > The test script inserts a single user, company and terms row, then in > new transaction loads the company and adds a new user. If you look at > the SQL output, you should see that it loads the company.terms > relationship, which doesn't seem like it should be necessary. > > I think it's due to the following code from history_meta.py: > > if not obj_changed: > # not changed, but we have relationships. OK > # check those too > for prop in obj_mapper.iterate_properties: > if isinstance(prop, RelationshipProperty) and \ > attributes.get_history(obj, prop.key).has_changes(): > for p in prop.local_columns: > if p.foreign_keys: > obj_changed = True > break > if obj_changed is True: > break > > I can't figure out the circumstances when this should be necessary - > can someone explain it to me? > > Thanks a lot, > > Simon
Doh, forgot the test script: import sqlalchemy as sa import sqlalchemy.orm as saorm from sqlalchemy.ext.declarative import declarative_base from history_meta import Versioned, versioned_session Base = declarative_base() class Terms(Base): __tablename__ = 'terms' id = sa.Column(sa.Integer(), primary_key=True) version = sa.Column(sa.Integer(), default=1) terms = sa.Column(sa.UnicodeText()) class Company(Versioned, Base): __tablename__ = 'company' id = sa.Column(sa.Integer(), primary_key=True) name = sa.Column(sa.Unicode(60)) termsid = sa.Column(sa.Integer, sa.ForeignKey(Terms.id), nullable=False) terms = saorm.relationship(Terms) class User(Base): __tablename__ = 'user' id = sa.Column(sa.Integer(), primary_key=True) name = sa.Column(sa.Unicode(60)) companyid = sa.Column(sa.Integer, sa.ForeignKey(Company.id), nullable=False) company = saorm.relationship(Company, backref='members') def test(): engine = sa.create_engine('sqlite:///:memory:', echo=True) Session = saorm.sessionmaker(bind=engine) versioned_session(Session) Base.metadata.create_all(engine) session = Session() session.add( User(name='Simon', company=Company(name='whatever', terms=Terms(version=1)) ) ) session.commit() company = session.query(Company).first() u = User(name='Larry', company=company) session.add(u) print '\n\n' + '#' * 70 + '\n' session.flush() if __name__ == '__main__': test() -- 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.