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