On 9/21/2010 8:17 PM, Michael Bayer wrote:
It definitely does not attempt an INSERT if id_ is set to a non-None value, 
assuming that row already exists in the DB, without something else in your 
model/usage causing that to happen.    If id_ is None or the given id_ doesn't 
exist in the DB, you get an INSERT.   auct_id has no direct effect here.

that also makes no sense since if you set "auct_id" manually, assuming 
old.auct_id is not None, it wouldn't be None in the UPDATE statement.

These behaviors (opposite what we expect) are what I'm indeed seeing.

As usual, distilling down the behavior that appears wrong into a single file

Attached.

I'll be thrilled if you can figure out what really stupid thing I'm doing to cause this.

As always, many thanks for your help.

Michael

--
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To post to this group, send email to sqlalch...@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.

from datetime import datetime, date

from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import (Column, Integer, String, Date, Boolean, Numeric, Enum,
                        DateTime, ForeignKey)
from sqlalchemy.orm import relationship, backref                        


Base = declarative_base()
Session = sessionmaker()


#------------------------------------------------------------------------------
class Car(Base):
    __tablename__ = 'cars'
    id_ = Column(Integer, primary_key=True)
    lane = Column(String, nullable=False)
    make = Column(String, nullable=False, default='')
    auct_id = Column(Integer, ForeignKey('auctions.id_'), nullable=False)
    auction = relationship('Auction', backref=backref('cars', order_by=lane))
                
    def __init__(self, lane=None, make='', auction=None):
        self.lane = lane
        self.make = make
        self.auction = auction
        
    def __repr__(self):
        return '<Car %d: %s %s>' % (self.id_, self.lane, self.make)
    
#------------------------------------------------------------------------------
class Auction(Base):
    __tablename__ = 'auctions'
    id_ = Column(Integer, primary_key=True)
    date = Column(Date, nullable=False, index=True)
    
    def __init__(self, date=None):
        self.date = date

    def __repr__(self):
        date = self.date.strftime('%Y-%m-%d')
        return '<Auction  %d: %s>' % (self.id_, date)


 #------------------------------------------------------------------------------
def main():
    url = 'sqlite:///:memory:'
    engine = create_engine(url, echo=True)
    metadata = Base.metadata
    Session.configure(bind=engine)
    metadata.create_all(engine)
    sess = Session()
        
    # create a minimal car to test against
    auct = Auction(date.today())  # simulated current auction
    sess.add(auct)
    old = Car(lane='A100', make='NISSAN', auction=auct)
    sess.add(old)
    sess.commit()
    
    # Now try to blank that car record
    new = Car()  # create a new empty car object
    new.id_ = old.id_          # save the pkey
    new.lane = old.lane        # can't be null
    new.auct_id = old.auct_id  # can't be null
    # Uncomment these 2 lines to see it try to do INSERT instead of UPDATE
    #new.auction = old.auction
    #sess.expunge(old)
    print new.id_, old.id_, new.auct_id, old.auct_id, new.auction, new, old
    new = sess.merge(new)
    print new.id_, old.id_, new.auct_id, old.auct_id, new.auction, new, old
    sess.commit()
    
    
if __name__ == "__main__":
    main()

Reply via email to