Re: [sqlalchemy] Objects inadvertently being added to session
Hi Mike, Thanks so much for the reply and the pointer. Since I never added anything to the session explicitly, I think I was missing that loading an object implicitly adds that object to the session - which does make sense. Is that right ? thanks again, terry On Monday, June 15, 2015 at 11:26:39 AM UTC-4, Michael Bayer wrote: On 6/15/15 11:12 AM, T Mark wrote: Hi there, I have been pulling my hair out on this one. I understood that objects make it into the session only due to an explicit call to add(). or if they are associated with a parent object that is added to the Session via add(), or if they are associated with an object that is already present in a Session via add(); this also will occur for backrefs, e.g. A is in the session, B.a is referred to A, B.a has a backref A.bs, therefore B is now added. This is configurable. But, I seem to be seeing objects being added without my explicitly doing so. Is this to be expected ? yes. please see: http://docs.sqlalchemy.org/en/rel_1_0/orm/cascades.html?highlight=cascades For instance, I want to establish a many-to-many relationship between two classes: say, for the purposes here, Person and Kid. test= create table persons (id SERIAL NOT NULL); test= CREATE TABLE person_to_kids (person_id INT NOT NULL, kid_id INT NOT NULL); test= create table kids (id SERIAL NOT NULL, name TEXT NOT NULL); test= insert into kids (name) VALUES ('Fred'); test= insert into kids (name) VALUES ('Barney'); person_to_kids = Table('person_to_kids', Base.metadata, Column('person_id', Integer, ForeignKey(' persons.id')), Column('kid_id', Integer, ForeignKey('kids.id'))) class Person(Base): __tablename__ = 'persons' id = Column('id', Integer, primary_key = True) def __init__(self, kids = []): kids = Kid.get_kids(kid_names = kids) print(__init__ before kids assignment) print(session.new) Assigning to self.kids here seems to add self to session ??? self.kids=kids print(After assignment to self.kids) print(session.new) class Kid(Base): __tablename__ = 'kids' id = Column(Integer, primary_key = True) name = Column(String) parents = relationship(Person, secondary = person_to_kids, backref=kids) def __init__(self, name = None): self.name = name @staticmethod def get_kids(kid_names = []): kids = [] for name in kid_names: # find first kid target_set = session.query(Kid).filter(Kid.name == name).first() kids.append(target_set) return kids What is puzzling me is that, if I have a collection of Kid objects, and I assign it to the kids collection in a Person, the Person object seems to be automatically added to the session and marked as pending, even if I have not added it. For instance, if the Persons table is empty: test= select * from persons; id (0 rows) and I run the following code: print(session.new) obj = Person(kids = ['Barney', 'Fred']) print(obj has been created) print(session.new) session.commit() The output shows that the Person object is added immediately after the assignment to obj.kids, without any call to session.add() anywhere in the code: IdentitySet([]) __init__ before kids assignment IdentitySet([]) After assignment to self.kids IdentitySet([__main__.Person object at 0x7fb6ce447b10]) obj has been created IdentitySet([__main__.Person object at 0x7fb6ce447b10]) And indeed, due to the commit() at the end, the person object makes it into the database: test= select * from persons; id 10 (1 row) But, I understood that objects (only) make it into a session by virtue of being explicitly added. So, is this the correct behavior, or am I misunderstanding something ? If I'm not misunderstanding this all, the complete code is at https://github.com/NuggyBuggy/sqlalchemy_question.git . Thanks for reading, terry -- 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. 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
[sqlalchemy] Re: Objects inadvertently being added to session
I forgot to mention: I'm using: - Python 2.7.6 on Linux, - SQLAlchemy version 0.9.9. - PostgreSQL 9.3 Thanks - terry On Monday, June 15, 2015 at 11:12:54 AM UTC-4, T Mark wrote: Hi there, I have been pulling my hair out on this one. I understood that objects make it into the session only due to an explicit call to add(). But, I seem to be seeing objects being added without my explicitly doing so. Is this to be expected ? For instance, I want to establish a many-to-many relationship between two classes: say, for the purposes here, Person and Kid. test= create table persons (id SERIAL NOT NULL); test= CREATE TABLE person_to_kids (person_id INT NOT NULL, kid_id INT NOT NULL); test= create table kids (id SERIAL NOT NULL, name TEXT NOT NULL); test= insert into kids (name) VALUES ('Fred'); test= insert into kids (name) VALUES ('Barney'); person_to_kids = Table('person_to_kids', Base.metadata, Column('person_id', Integer, ForeignKey(' persons.id')), Column('kid_id', Integer, ForeignKey('kids.id'))) class Person(Base): __tablename__ = 'persons' id = Column('id', Integer, primary_key = True) def __init__(self, kids = []): kids = Kid.get_kids(kid_names = kids) print(__init__ before kids assignment) print(session.new) Assigning to self.kids here seems to add self to session ??? self.kids=kids print(After assignment to self.kids) print(session.new) class Kid(Base): __tablename__ = 'kids' id = Column(Integer, primary_key = True) name = Column(String) parents = relationship(Person, secondary = person_to_kids, backref=kids) def __init__(self, name = None): self.name = name @staticmethod def get_kids(kid_names = []): kids = [] for name in kid_names: # find first kid target_set = session.query(Kid).filter(Kid.name == name).first() kids.append(target_set) return kids What is puzzling me is that, if I have a collection of Kid objects, and I assign it to the kids collection in a Person, the Person object seems to be automatically added to the session and marked as pending, even if I have not added it. For instance, if the Persons table is empty: test= select * from persons; id (0 rows) and I run the following code: print(session.new) obj = Person(kids = ['Barney', 'Fred']) print(obj has been created) print(session.new) session.commit() The output shows that the Person object is added immediately after the assignment to obj.kids, without any call to session.add() anywhere in the code: IdentitySet([]) __init__ before kids assignment IdentitySet([]) After assignment to self.kids IdentitySet([__main__.Person object at 0x7fb6ce447b10]) obj has been created IdentitySet([__main__.Person object at 0x7fb6ce447b10]) And indeed, due to the commit() at the end, the person object makes it into the database: test= select * from persons; id 10 (1 row) But, I understood that objects (only) make it into a session by virtue of being explicitly added. So, is this the correct behavior, or am I misunderstanding something ? If I'm not misunderstanding this all, the complete code is at https://github.com/NuggyBuggy/sqlalchemy_question.git . Thanks for reading, terry -- 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/d/optout.
[sqlalchemy] Objects inadvertently being added to session
Hi there, I have been pulling my hair out on this one. I understood that objects make it into the session only due to an explicit call to add(). But, I seem to be seeing objects being added without my explicitly doing so. Is this to be expected ? For instance, I want to establish a many-to-many relationship between two classes: say, for the purposes here, Person and Kid. test= create table persons (id SERIAL NOT NULL); test= CREATE TABLE person_to_kids (person_id INT NOT NULL, kid_id INT NOT NULL); test= create table kids (id SERIAL NOT NULL, name TEXT NOT NULL); test= insert into kids (name) VALUES ('Fred'); test= insert into kids (name) VALUES ('Barney'); person_to_kids = Table('person_to_kids', Base.metadata, Column('person_id', Integer, ForeignKey('persons.id')), Column('kid_id', Integer, ForeignKey('kids.id'))) class Person(Base): __tablename__ = 'persons' id = Column('id', Integer, primary_key = True) def __init__(self, kids = []): kids = Kid.get_kids(kid_names = kids) print(__init__ before kids assignment) print(session.new) Assigning to self.kids here seems to add self to session ??? self.kids=kids print(After assignment to self.kids) print(session.new) class Kid(Base): __tablename__ = 'kids' id = Column(Integer, primary_key = True) name = Column(String) parents = relationship(Person, secondary = person_to_kids, backref=kids) def __init__(self, name = None): self.name = name @staticmethod def get_kids(kid_names = []): kids = [] for name in kid_names: # find first kid target_set = session.query(Kid).filter(Kid.name == name).first() kids.append(target_set) return kids What is puzzling me is that, if I have a collection of Kid objects, and I assign it to the kids collection in a Person, the Person object seems to be automatically added to the session and marked as pending, even if I have not added it. For instance, if the Persons table is empty: test= select * from persons; id (0 rows) and I run the following code: print(session.new) obj = Person(kids = ['Barney', 'Fred']) print(obj has been created) print(session.new) session.commit() The output shows that the Person object is added immediately after the assignment to obj.kids, without any call to session.add() anywhere in the code: IdentitySet([]) __init__ before kids assignment IdentitySet([]) After assignment to self.kids IdentitySet([__main__.Person object at 0x7fb6ce447b10]) obj has been created IdentitySet([__main__.Person object at 0x7fb6ce447b10]) And indeed, due to the commit() at the end, the person object makes it into the database: test= select * from persons; id 10 (1 row) But, I understood that objects (only) make it into a session by virtue of being explicitly added. So, is this the correct behavior, or am I misunderstanding something ? If I'm not misunderstanding this all, the complete code is at https://github.com/NuggyBuggy/sqlalchemy_question.git . Thanks for reading, terry -- 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/d/optout.