Hi Michael, thanks for the reply. I thought I had tested the code, but I did not do so properly.
The essence of the logic I posted works. Here are the few corrections: You are right that I should not use strings for partition_id when it is defined as integer. This is a piece of test code I cooked up. In the actual production code, partition_id comes from another API and it is already integer. The other bug I had in my code was that: in the lines: for db_part in db_parts: dev_part = dev_parts.get(db_part.partition_id, None) if dev_part is not None: # update db partition with that from device db_part.partition_id = dev_part.partition_id db_part.partition_name = dev_part.partition_name # remove the device partition since we have updated the db del dev_part[db_part.partition_id] The last line should have read: del dev_parts[db_part.partition_id] You also had mentioned that "the code doesn’t seem to show anything that would result in any DELETEs emitted". I am using a list comprehension to update the list of test_partitions associated with the test_device database entry. This list comprehension updates the test_partition list ('partitions' attribute) for the device by keeping only those partitions that are in the dict data structure (simulated to get data from a data collector on the device). The lines of code that updates the 'partitions' attribute is: # First delete partitions in database that are not in device db_parts[:] = [db_part for db_part in db_parts if dev_parts.get(db_part.partition_id, None) is not None] db_parts was set in an earlier line of code as follows: ndev = sess.query(TestDevice).filter(TestDevice.dns_name=='testdev3').first() print 'ndev:', ndev if ndev is not None: db_parts = ndev.partitions # <--- partitions attribute set through backref on TestPartition object. After I made the changes, the code works as expected: Before update, the test_partition table: basicinv=> select * from test_partition ; id | partition_name | partition_id | device_id ----+----------------+--------------+----------- 42 | test456 | 456 | 41 43 | test345 | 345 | 41 44 | test123 | 123 | 41 (3 rows) After running the code: basicinv=> select * from test_partition ; id | partition_name | partition_id | device_id ----+----------------+--------------+----------- 42 | test456-2 | 456 | 41 43 | test345-1 | 345 | 41 45 | test678 | 678 | 41 46 | test567 | 567 | 41 (4 rows) basicinv=> As I expected, partitions with primary keys 42 and 43 got updated (ie. not deleted and inserted with new primary key rows). Thanks for your feedback. On Monday, July 21, 2014 7:13:46 AM UTC-7, Michael Bayer wrote: > > not to mention you’re using strings to set integer values, again a bad > idea, can only confuse your database: > > part.partition_id = ‘345’ # <— this is a string > > > partition_id = sa.Column(sa.Integer, nullable=False) # <— should be integer > > > with this program you need to create a short test case that actually runs > and step through it with pdb as well as echo=True to analyze more > accurately what’s happening and when. > > > > On Jul 21, 2014, at 10:10 AM, Michael Bayer <mik...@zzzcomputing.com > <javascript:>> wrote: > > the code there doesn’t seem to show anything that would result in any > DELETEs emitted. a DELETE here would only occur if you deassociated a > TestDevice and a TestPartition by removing from the TestDevice.partitions > collection or setting a TestPartition.device to None, and I don’t see that. > All of the manipulations you’re doing with part.partition_id have nothing > to do with any of that, SQLAlchemy’s relationships have no idea what you’re > doing with those, and overall it's a bad idea to mix the usage of > “obj.foreign_key = <id>” along with direct manipulation of the relationship > (where you say dev_part.device = ndev) together. SQLAlchemy’s > relationship management code knows nothing about any of those foreign key > sets. See > http://docs.sqlalchemy.org/en/rel_0_9/faq.html#i-set-the-foo-id-attribute-on-my-instance-to-7-but-the-foo-attribute-is-still-none-shouldn-t-it-have-loaded-foo-with-id-7 > . > > > > > > > > On Jul 21, 2014, at 2:55 AM, Bala Ramakrishnan <bal...@gmail.com > <javascript:>> wrote: > > I had asked this question on Stack Overflow. The details are at this link: > > > http://stackoverflow.com/questions/24836816/updating-a-few-children-in-one-to-many-relationship-deletes-all-rows-and-adds-ne > > The summary is I have a parent class A and a bidirectional one-to-many > relationship with class B. When I update the class B list for an instance > of A, the update may involve deleting some class B instances, updating some > of them, and adding new ones. However, I find that SqlAlchemy deletes all > ROWS of classB, and the inserts the necessary new rows. I would have > expected SqlAchemy to insert only new rows, not delete and add those rows > that are being updated. Do you know what is wrong with my code? > > Thanks. > > > -- > 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 http://groups.google.com/group/sqlalchemy. > For more options, visit https://groups.google.com/d/optout. > > > > -- > 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 http://groups.google.com/group/sqlalchemy. > For more options, visit https://groups.google.com/d/optout. > > > -- 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 http://groups.google.com/group/sqlalchemy. For more options, visit https://groups.google.com/d/optout.