this also allows "deferred" column properties to remain untouched by a save operation
if they werent affected.
t = sql.text(text, engine=self.primarytable.engine)
return self.instances(t.execute(**params))
- def _getattrbycolumn(self, obj, column):
+ def _getpropbycolumn(self, column):
try:
prop = self.columntoproperty[column.original]
except KeyError:
raise "Column '%s.%s' is not available, due to conflicting property '%s':%s" % (column.table.name, column.name, column.key, repr(prop))
except KeyError:
raise "No column %s.%s is configured on mapper %s..." % (column.table.name, column.name, str(self))
-
- return prop[0].getattr(obj)
+ return prop[0]
+
+ def _getattrbycolumn(self, obj, column):
+ prop = self._getpropbycolumn(column)
+ return prop.getattr(obj)
def _setattrbycolumn(self, obj, column, value):
self.columntoproperty[column.original][0].setattr(obj, value)
# print "SAVE_OBJ we are " + hash_key(self) + " obj: " + obj.__class__.__name__ + repr(id(obj))
params = {}
- if not hasattr(obj, "_instance_key"):
+ isinsert = not hasattr(obj, "_instance_key")
+ if isinsert:
self.extension.before_insert(self, obj)
+ hasdata = False
for col in table.columns:
#if col.primary_key:
if pk.has_key(col):
if value is not None:
params[col.key] = value
else:
- params[col.key] = self._getattrbycolumn(obj, col)
+ if not isinsert:
+ prop = self._getpropbycolumn(col)
+ history = prop.get_history(obj, passive=True)
+ if history:
+ a = history.added_items()
+ if len(a):
+ params[col.key] = a[0]
+ hasdata = True
+ else:
+ params[col.key] = self._getattrbycolumn(obj, col)
- if hasattr(obj, "_instance_key"):
- update.append(params)
+ if not isinsert:
+ if hasdata:
+ update.append(params)
else:
insert.append((obj, params))
uow.register_saved_object(obj)
for col in self.pks_by_table[table]:
clause.clauses.append(col == sql.bindparam(col.table.name + "_" + col.key))
statement = table.update(clause)
- c = statement.execute(*update)
- if table.engine.supports_sane_rowcount() and c.rowcount != len(update):
- raise "ConcurrencyError - updated rowcount %d does not match number of objects updated %d" % (c.cursor.rowcount, len(update))
+ rows = 0
+ for rec in update:
+ c = statement.execute(rec)
+ rows += c.cursor.rowcount
+ if table.engine.supports_sane_rowcount() and rows != len(update):
+ raise "ConcurrencyError - updated rowcount %d does not match number of objects updated %d" % (rows, len(update))
if len(insert):
import sys
statement = table.insert()
return getattr(object, self.key, None)
def setattr(self, object, value):
setattr(object, self.key, value)
+ def get_history(self, obj, passive=False):
+ return objectstore.global_attributes.get_history(obj, self.key, passive=passive)
def hash_key(self):
return "ColumnProperty(%s)" % repr([hash_key(c) for c in self.columns])
print o2.description
self.assert_sql(db, go, [
- ("SELECT orders.order_id AS orders_order_id, orders.user_id AS orders_user_id, orders.isopen AS orders_isopen FROM orders ORDER BY orders.oid", {}),
+ ("SELECT orders.order_id AS orders_order_id, orders.user_id AS orders_user_id, orders.isopen AS orders_isopen FROM orders ORDER BY orders.%s" % orders.rowid_column.key, {}),
("SELECT orders.description AS orders_description FROM orders WHERE orders.order_id = :orders_order_id", {'orders_order_id':3})
])
+
+ def testsave(self):
+ m = mapper(Order, orders, properties={
+ 'description':deferred(orders.c.description)
+ })
+
+ l = m.select()
+ o2 = l[2]
+ o2.isopen = 1
+ objectstore.commit()
def testgroup(self):
"""tests deferred load with a group"""
o2 = l[2]
print o2.opened, o2.description, o2.userident
self.assert_sql(db, go, [
- ("SELECT orders.order_id AS orders_order_id FROM orders ORDER BY orders.oid", {}),
+ ("SELECT orders.order_id AS orders_order_id FROM orders ORDER BY orders.%s" % orders.rowid_column.key, {}),
("SELECT orders.user_id AS orders_user_id, orders.description AS orders_description, orders.isopen AS orders_isopen FROM orders WHERE orders.order_id = :orders_order_id", {'orders_order_id':3})
])
l = m2.select()
print l[2].user_id
self.assert_sql(db, go, [
- ("SELECT orders.order_id AS orders_order_id, orders.description AS orders_description, orders.isopen AS orders_isopen FROM orders ORDER BY orders.oid", {}),
+ ("SELECT orders.order_id AS orders_order_id, orders.description AS orders_description, orders.isopen AS orders_isopen FROM orders ORDER BY orders.%s" % orders.rowid_column.key, {}),
("SELECT orders.user_id AS orders_user_id FROM orders WHERE orders.order_id = :orders_order_id", {'orders_order_id':3})
])
objectstore.clear()
l = m3.select()
print l[3].user_id
self.assert_sql(db, go, [
- ("SELECT orders.order_id AS orders_order_id, orders.user_id AS orders_user_id, orders.description AS orders_description, orders.isopen AS orders_isopen FROM orders ORDER BY orders.oid", {}),
+ ("SELECT orders.order_id AS orders_order_id, orders.user_id AS orders_user_id, orders.description AS orders_description, orders.isopen AS orders_isopen FROM orders ORDER BY orders.%s" % orders.rowid_column.key, {}),
])
def testdeepoptions(self):
{'user_name': 'imnewlyadded'}
),
(
- "UPDATE email_addresses SET user_id=:user_id, email_address=:email_address WHERE email_addresses.address_id = :email_addresses_address_id",
- lambda: [
- {'email_address': 'imnew@foo.bar', 'user_id': objects[2].user.user_id, 'email_addresses_address_id': objects[2].address_id},
- {'email_address': 'adsd5@llala.net', 'user_id': objects[3].user.user_id, 'email_addresses_address_id': objects[3].address_id}
- ]
- )
+ "UPDATE email_addresses SET email_address=:email_address WHERE email_addresses.address_id = :email_addresses_address_id",
+ lambda: [{'email_address': 'imnew@foo.bar', 'email_addresses_address_id': objects[2].address_id}]
+ ),
+ (
+ "UPDATE email_addresses SET user_id=:user_id WHERE email_addresses.address_id = :email_addresses_address_id",
+ lambda: [{'user_id': objects[3].user.user_id, 'email_addresses_address_id': objects[3].address_id}]
+ ),
+
])
l = sql.select([users, addresses], sql.and_(users.c.user_id==addresses.c.address_id, addresses.c.address_id==a.address_id)).execute()
self.echo( repr(l.fetchone().row))
[{'users_user_id': u2.user_id, 'user_name': 'user2modified'}]
),
(
- "UPDATE email_addresses SET user_id=:user_id, email_address=:email_address WHERE email_addresses.address_id = :email_addresses_address_id",
- [
- {'email_address': 'emailaddress3', 'user_id': u1.user_id, 'email_addresses_address_id': a3.address_id},
- {'email_address': 'emailaddress1', 'user_id': None, 'email_addresses_address_id': a1.address_id}
- ]
+ "UPDATE email_addresses SET user_id=:user_id WHERE email_addresses.address_id = :email_addresses_address_id",
+ [{'user_id': u1.user_id, 'email_addresses_address_id': a3.address_id}]
+ ),
+ ("UPDATE email_addresses SET user_id=:user_id WHERE email_addresses.address_id = :email_addresses_address_id",
+ [{'user_id': None, 'email_addresses_address_id': a1.address_id}]
)
])
objects[5].keywords.append(k)
self.assert_sql(db, lambda:objectstore.commit(), [
(
- "UPDATE items SET order_id=:order_id, item_name=:item_name WHERE items.item_id = :items_item_id",
- [{'item_name': 'item4updated', 'order_id': None, 'items_item_id': objects[4].item_id}]
+ "UPDATE items SET item_name=:item_name WHERE items.item_id = :items_item_id",
+ [{'item_name': 'item4updated', 'items_item_id': objects[4].item_id}]
),
(
"INSERT INTO keywords (name) VALUES (:name)",