Thank you for your answer. I think detaching and doing a session.flush() is 
a good enough solution for now.

Den onsdag 30 augusti 2017 kl. 16:31:03 UTC+2 skrev Mike Bayer:
>
> On Wed, Aug 30, 2017 at 7:52 AM, Levon Saldamli <levo...@gmail.com 
> <javascript:>> wrote: 
> > I'm trying to have to objects with a one-to-one relationship, e.g. User 
> and 
> > Address, with a UniqueConstraint for user.id in the address table 
> (names 
> > changed from the real code). But when user.address is updated, the 
> commit 
> > fails because the UniqueConstraint is broken, probably because 
> SqlAlchemy 
> > inserts the new address into the table before removing the old one. If I 
> set 
> > the address to None, commit and then set to a new address, it works 
> fine. Is 
> > this a known issue or limitation, and is there a possibility that this 
> will 
> > be supported in the future? 
>
> You've hit a classic issue, which is known as the "DELETE before 
> INSERT" problem: 
>
>
> https://bitbucket.org/zzzeek/sqlalchemy/issues/2501/the-delete-before-insert-problem
>  
> <https://www.google.com/url?q=https%3A%2F%2Fbitbucket.org%2Fzzzeek%2Fsqlalchemy%2Fissues%2F2501%2Fthe-delete-before-insert-problem&sa=D&sntz=1&usg=AFQjCNEfVND7dK1_OEq5fU2bpuNfRGodTQ>
>  
>
> There is in fact a solution attached to that issue in the form of a 
> new option that would be added to the mapper() where you provide a set 
> of columns that need to be maintained as unique. 
>
> The reason it hasn't found its way in yet is because it's not clear 
> how well received this option would be, what the real demand is for it 
> as it's a fair it of work, or how well it works in real world use 
> cases - you can see in the comments that everyone who tries it out 
> still has some other aspects of their problem it does not solve, and 
> then for whatever reason seem to move on from it.   I've yet to have 
> someone say hey this solved my problem. 
>
> This is partially because the workaround is pretty simple, you just 
> detach the first object, do session.flush() to delete it, then attach 
> the new one. 
>
> Let me know which approach you'd like to proceed with. 
>
>
> > 
> > Full example with the failing commit below. SqlAlchemy version used is 
> > 1.1.13. The problem is reproducible with both sqlite and postgresql. 
> > 
> > from sqlalchemy import create_engine 
> > from sqlalchemy.ext.declarative import declarative_base 
> > from sqlalchemy import Column, Integer, String 
> > from sqlalchemy import ForeignKey 
> > from sqlalchemy.orm import relationship 
> > from sqlalchemy import UniqueConstraint 
> > 
> > engine = create_engine('sqlite:///:memory:', echo=True) 
> > 
> > 
> > Base = declarative_base() 
> > 
> > class User(Base): 
> >     __tablename__ = 'users' 
> >     id = Column(Integer, primary_key=True) 
> >     name = Column(String) 
> >     fullname = Column(String) 
> > 
> >     address = relationship("Address", uselist=False, 
> back_populates="user", 
> > cascade="all, delete-orphan") 
> > 
> >     def __repr__(self): 
> >        return "<User(name='%s', fullname='%s', id='%s')>" % ( 
> >                             self.name, self.fullname, self.id) 
> > 
> > 
> > class Address(Base): 
> > __tablename__ = 'addresses' 
> > id = Column(Integer, primary_key=True) 
> > email_address = Column(String, nullable=False) 
> > user_id = Column(Integer, ForeignKey('users.id')) 
> > 
> > user = relationship("User", back_populates="address") 
> > __table_args__ = (UniqueConstraint('user_id', 
> > name='_one_unique_address_per_user_uc'),) 
> > 
> > def __repr__(self): 
> > return "<Address(email_address='%s')>" % self.email_address 
> > 
> > 
> > Base.metadata.create_all(engine) 
> > 
> > ed_user = User(name='ed', fullname='Ed Jones') 
> > 
> > from sqlalchemy.orm import sessionmaker 
> > Session = sessionmaker(bind=engine) 
> > 
> > 
> > ed_user.address = Address(email_address='f..._at_bar.com <javascript:>') 
>
> > 
> > session = Session() 
> > session.add(ed_user) 
> > session.commit() 
> > 
> > ed_user.address = Address(email_address='new_address_at_bar.com 
> <javascript:>') 
> > session.add(ed_user) 
> > session.commit() 
> > 
> > 
> > 
> > 
> > 
> > -- 
> > 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:>. 
> > To post to this group, send email to 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.

Reply via email to