from sqlalchemy import * from sqlalchemy.orm import * from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base() atob = Table( 'atob', Base.metadata, Column('aid', ForeignKey('a.id'), primary_key=True), Column('bid', ForeignKey('b.id'), primary_key=True) ) class A(Base): __tablename__ = 'a' id = Column(Integer, primary_key=True) bs = relationship("B", secondary=atob) class B(Base): __tablename__ = 'b' id = Column(Integer, primary_key=True) e = create_engine("sqlite://", echo=True) Base.metadata.create_all(e) session = Session(e) a1 = A(bs=[B(), B(), B()]) session.add(a1) session.commit() # please illustrate failure here # # Example 1. M2M is empty after being made transient. # assert len(a1.bs) == 3 make_transient(a1) a1.id = None session.add(a1) session.commit() assert len(a1.bs) == 0 # # Example 2. M2M remains empty ever after being assigned relationships. # model = session.query(A).first() bs = model.bs.copy() assert len(bs) == 3 make_transient(model) model.id = None model.bs = bs session.add(model) session.commit() assert len(model.bs) == 0 # # Example 3. M2M is populated from fresh query. # model = session.query(A).first() bs = session.query(B).all() assert len(bs) == 3 make_transient(model) model.id = None model.bs = bs session.add(model) session.commit() assert len(model.bs) == 3 On Friday, October 28, 2016 at 9:47:44 AM UTC-4, Mike Bayer wrote: > > here we are, please complete and return, thanks > > from sqlalchemy import * > from sqlalchemy.orm import * > from sqlalchemy.ext.declarative import declarative_base > > Base = declarative_base() > > atob = Table( > 'atob', Base.metadata, > Column('aid', ForeignKey('a.id'), primary_key=True), > Column('bid', ForeignKey('b.id'), primary_key=True) > ) > > > class A(Base): > __tablename__ = 'a' > id = Column(Integer, primary_key=True) > bs = relationship("B", secondary=atob) > > > class B(Base): > __tablename__ = 'b' > id = Column(Integer, primary_key=True) > > e = create_engine("sqlite://", echo=True) > Base.metadata.create_all(e) > > > session = Session(e) > > a1 = A(bs=[B(), B(), B()]) > session.add(a1) > session.commit() > > > # please illustrate failure here > > > > > > On 10/28/2016 09:13 AM, Colton Allen wrote: > > Okay I see. That does remove the error. But I am having trouble saving > > the relationship. Check the example code. It is much clearer than I > am. > > > > If I query a new set of items or specify an item model instance it will > > save perfectly. But all of the instances in the instrumented list will > > not save to the relationship. Is there a further expiration step? > > > > # This works > > session.expire(model, ['items']) > > make_transient(model) > > model.items = ItemModel.query.all() # [<ItemModel>] > > session.add(model) > > session.commit() > > > > Test.query.first().items # [<ItemModel>] > > > > # This does not save > > items = model.items.copy() # [<ItemModel>] > > session.expire(model, ['items']) > > make_transient(model) > > model.items = items > > session.add(model) > > session.commit() > > > > Test.query.first().items # [] > > > > On Thursday, October 27, 2016 at 6:15:39 PM UTC-4, Mike Bayer wrote: > > > > you'd say: > > > > session.expire(model, ["items"]) > > > > > > > > On 10/27/2016 04:47 PM, Colton Allen wrote: > > > Sorry I must have combined multiple attempts into one example. > > When you > > > say expire the relationship, what do you mean? > > > > > > > > > On Thursday, October 27, 2016 at 4:30:36 PM UTC-4, Mike Bayer > wrote: > > > > > > Hello - > > > > > > > > > I've rebuilt your fragment into a full example in order to > > determine > > > what the behavior is here, as make_transient() has no defined > > behavior > > > for loaded relationships. > > > > > > Your error does not reproduce with your code fragment as > > given, because > > > you are setting the list of items to itself, and this means > > there is no > > > history at all; the unit of work will ignore it. > > > > > > Setting the list to a series of three brand new secondary > items > > > produces > > > the error you see because this generates deletion events for > the > > > existing objects which fail because the state of the object is > > > transient. > > > > > > The solution is to expire the relationship attribute first so > > that > > > it is > > > reset for the transient state. > > > > > > > > > > > > > > > On 10/27/2016 03:43 PM, Colton Allen wrote: > > > > I want to create a new row with all of the same data. > However, > > > (using > > > > make_transient) the many-to-many "items" relationship > doesn't > > > carry over > > > > to the new model. When I manually set the items I recieve a > > > > "StaleDataError". How can I insert the many-to-many > > relationships so > > > > this does not happen? > > > > * > > > > * > > > > * > > > > My code:* > > > > > > > > class Test(Model): > > > > id = Column(Integer, primary_key=True) > > > > items = orm.relationship('ItemModel', > > secondary=test_item_table) > > > > > > > > > > > > model = Test.query.first() > > > > list_of_items = model.items.copy() > > > > > > > > make_transient(model) > > > > model.id <http://model.id> <http://model.id> = None > > > > model.items = list_of_items > > > > > > > > session.add(model) > > > > session.commit() > > > > > > > > # sqlalchemy.orm.exc.StaleDataError: DELETE statement on > table > > > > 'test_item' expected to delete 1 row(s); Only 0 were > matched. > > > > > > > > -- > > > > SQLAlchemy - > > > > The Python SQL Toolkit and Object Relational Mapper > > > > > > > > http://www.sqlalchemy.org/ > > > > > > > > To post example code, please provide an MCVE: Minimal, > > Complete, and > > > > Verifiable Example. See http://stackoverflow.com/help/mcve > > <http://stackoverflow.com/help/mcve> > > > <http://stackoverflow.com/help/mcve > > <http://stackoverflow.com/help/mcve>> for a full > > > > description. > > > > --- > > > > 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:> > > > > <mailto:sqlalchemy+unsubscr...@googlegroups.com > <javascript:> > > <javascript:> <javascript:>>. > > > > To post to this group, send email to > sqlal...@googlegroups.com > > > <javascript:> > > > > <mailto:sqlal...@googlegroups.com <javascript:>>. > > > > Visit this group at > > https://groups.google.com/group/sqlalchemy > > <https://groups.google.com/group/sqlalchemy> > > > <https://groups.google.com/group/sqlalchemy > > <https://groups.google.com/group/sqlalchemy>>. > > > > For more options, visit https://groups.google.com/d/optout > > <https://groups.google.com/d/optout> > > > <https://groups.google.com/d/optout > > <https://groups.google.com/d/optout>>. > > > > > > -- > > > SQLAlchemy - > > > The Python SQL Toolkit and Object Relational Mapper > > > > > > http://www.sqlalchemy.org/ > > > > > > To post example code, please provide an MCVE: Minimal, Complete, > and > > > Verifiable Example. See http://stackoverflow.com/help/mcve > > <http://stackoverflow.com/help/mcve> for a full > > > description. > > > --- > > > 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:> > > > <mailto:sqlalchemy+unsubscr...@googlegroups.com <javascript:> > <javascript:>>. > > > To post to this group, send email to sqlal...@googlegroups.com > > <javascript:> > > > <mailto:sqlal...@googlegroups.com <javascript:>>. > > > Visit this group at https://groups.google.com/group/sqlalchemy > > <https://groups.google.com/group/sqlalchemy>. > > > For more options, visit https://groups.google.com/d/optout > > <https://groups.google.com/d/optout>. > > > > -- > > SQLAlchemy - > > The Python SQL Toolkit and Object Relational Mapper > > > > http://www.sqlalchemy.org/ > > > > To post example code, please provide an MCVE: Minimal, Complete, and > > Verifiable Example. See http://stackoverflow.com/help/mcve for a full > > description. > > --- > > 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:> > > <mailto:sqlalchemy+unsubscr...@googlegroups.com <javascript:>>. > > To post to this group, send email to sqlal...@googlegroups.com > <javascript:> > > <mailto:sqlal...@googlegroups.com <javascript:>>. > > Visit this group at https://groups.google.com/group/sqlalchemy. > > For more options, visit https://groups.google.com/d/optout. > -- SQLAlchemy - The Python SQL Toolkit and Object Relational Mapper http://www.sqlalchemy.org/ To post example code, please provide an MCVE: Minimal, Complete, and Verifiable Example. See http://stackoverflow.com/help/mcve for a full description. --- 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.