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()