- Added a callable-based DDL events interface, adds hooks
before and after Tables and MetaData create and drop.
+ - added generative where(<criterion>) method to delete()
+ and update() constructs which return a new object with
+ criterion joined to existing criterion via AND, just
+ like select().where().
+
- Added "ilike()" operator to column operations. Compiles to
ILIKE on postgres, lower(x) LIKE lower(y) on all
others. [ticket:727]
return e
def where(self, clause):
+ """return a new exists() construct with the given expression added to its WHERE clause, joined
+ to the existing clause via AND, if any."""
+
e = self._clone()
e.element = self.element.where(clause).self_group()
return e
class Update(_UpdateBase):
def __init__(self, table, whereclause, values=None, inline=False, **kwargs):
self.table = table
- self._whereclause = whereclause
+ if whereclause:
+ self._whereclause = _literal_as_text(whereclause)
+ else:
+ self._whereclause = None
self.inline = inline
self.parameters = self._process_colparams(values)
self._whereclause = clone(self._whereclause)
self.parameters = self.parameters.copy()
+ def where(self, whereclause):
+ """return a new update() construct with the given expression added to its WHERE clause, joined
+ to the existing clause via AND, if any."""
+
+ s = self._clone()
+ if s._whereclause is not None:
+ s._whereclause = and_(s._whereclause, _literal_as_text(whereclause))
+ else:
+ s._whereclause = _literal_as_text(whereclause)
+ return s
+
def values(self, v):
if len(v) == 0:
return self
class Delete(_UpdateBase):
def __init__(self, table, whereclause):
self.table = table
- self._whereclause = whereclause
+ if whereclause:
+ self._whereclause = _literal_as_text(whereclause)
+ else:
+ self._whereclause = None
def get_children(self, **kwargs):
if self._whereclause is not None:
else:
return ()
+ def where(self, whereclause):
+ """return a new delete() construct with the given expression added to its WHERE clause, joined
+ to the existing clause via AND, if any."""
+
+ s = self._clone()
+ if s._whereclause is not None:
+ s._whereclause = and_(s._whereclause, _literal_as_text(whereclause))
+ else:
+ s._whereclause = _literal_as_text(whereclause)
+ return s
+
def _copy_internals(self, clone=_clone):
self._whereclause = clone(self._whereclause)
def test_update(self):
self.assert_compile(update(table1, table1.c.myid == 7), "UPDATE mytable SET name=:name WHERE mytable.myid = :mytable_myid_1", params = {table1.c.name:'fred'})
+ self.assert_compile(table1.update().where(table1.c.myid==7).values({table1.c.myid:5}), "UPDATE mytable SET myid=:myid WHERE mytable.myid = :mytable_myid_1", checkparams={'myid':5, 'mytable_myid_1':7})
self.assert_compile(update(table1, table1.c.myid == 7), "UPDATE mytable SET name=:name WHERE mytable.myid = :mytable_myid_1", params = {'name':'fred'})
self.assert_compile(update(table1, values = {table1.c.name : table1.c.myid}), "UPDATE mytable SET name=mytable.myid")
self.assert_compile(update(table1, whereclause = table1.c.name == bindparam('crit'), values = {table1.c.name : 'hi'}), "UPDATE mytable SET name=:name WHERE mytable.name = :crit", params = {'crit' : 'notthere'}, checkparams={'crit':'notthere', 'name':'hi'})
def test_delete(self):
self.assert_compile(delete(table1, table1.c.myid == 7), "DELETE FROM mytable WHERE mytable.myid = :mytable_myid_1")
-
+ self.assert_compile(table1.delete().where(table1.c.myid == 7), "DELETE FROM mytable WHERE mytable.myid = :mytable_myid_1")
+ self.assert_compile(table1.delete().where(table1.c.myid == 7).where(table1.c.name=='somename'), "DELETE FROM mytable WHERE mytable.myid = :mytable_myid_1 AND mytable.name = :mytable_name_1")
+
def test_correlated_delete(self):
# test a non-correlated WHERE clause
s = select([table2.c.othername], table2.c.otherid == 7)
cc = re.sub(r'\n', '', str(c))
- self.assert_(cc == result, "\n'" + cc + "'\n does not match \n'" + result + "'")
+ self.assertEquals(cc, result)
if checkparams is not None:
- self.assert_(c.construct_params(params) == checkparams, "params dont match" + repr(c.params))
+ self.assertEquals(c.construct_params(params), checkparams)
class AssertMixin(PersistTest):
"""given a list-based structure of keys/properties which represent information within an object structure, and