The general idea is great though you probably want to use the @compiles decorator to link the compile function to the expression element, since that's the API point of extension - that would remove the need for the _compiler() call:
http://www.sqlalchemy.org/docs/core/compiler.html?highlight=compiles You probably don't need the _copy_internals() call either since insert/update/delete expressions aren't generally used with "clause adaption" (for a description of what that's all about, see http://techspot.zzzeek.org/2008/01/23/expression-transformations/ ). On Dec 22, 2010, at 8:51 AM, Tarek Ziadé wrote: > Hello, > > I need to add order_by, limit and offset support to Delete objects for > MySQL. Here's what I've done so far, which works. See the long paste > below, I use delete() on my tables. > > I would like to know if this is the right way to do things, or if I am > missing something. I am currently using 0.6.x > > Thanks ! > > Tarek > > > from sqlalchemy.sql.expression import _generative, Delete, _clone, ClauseList > from sqlalchemy import util > from sqlalchemy.sql.compiler import SQLCompiler > > class CustomCompiler(SQLCompiler): > > def visit_delete(self, delete_stmt): > self.stack.append({'from': set([delete_stmt.table])}) > self.isdelete = True > > text = "DELETE FROM " + self.preparer.format_table(delete_stmt.table) > > if delete_stmt._returning: > self.returning = delete_stmt._returning > if self.returning_precedes_values: > text += " " + self.returning_clause(delete_stmt, > delete_stmt._returning) > > if delete_stmt._whereclause is not None: > text += " WHERE " + self.process(delete_stmt._whereclause) > > if len(delete_stmt._order_by_clause) > 0: > text += " ORDER BY " + self.process(delete_stmt._order_by_clause) > > if delete_stmt._limit is not None or delete_stmt._offset is not None: > text += self.limit_clause(delete_stmt) > > if self.returning and not self.returning_precedes_values: > text += " " + self.returning_clause(delete_stmt, > delete_stmt._returning) > > self.stack.pop(-1) > > return text > > > class DeleteOrderBy(Delete): > > def __init__(self, table, whereclause, bind=None, returning=None, > order_by=None, limit=None, offset=None, **kwargs): > Delete.__init__(self, table, whereclause, bind, returning, **kwargs) > self._order_by_clause = ClauseList(*util.to_list(order_by) or []) > self._limit = limit > self._offset = offset > > @_generative > def order_by(self, *clauses): > self.append_order_by(*clauses) > > def append_order_by(self, *clauses): > if len(clauses) == 1 and clauses[0] is None: > self._order_by_clause = ClauseList() > else: > if getattr(self, '_order_by_clause', None) is not None: > clauses = list(self._order_by_clause) + list(clauses) > self._order_by_clause = ClauseList(*clauses) > > @_generative > def limit(self, limit): > self._limit = limit > > @_generative > def offset(self, offset): > self._offset = offset > > def _copy_internals(self, clone=_clone): > self._whereclause = clone(self._whereclause) > for attr in ('_order_by_clause',): > if getattr(self, attr) is not None: > setattr(self, attr, clone(getattr(self, attr))) > > def get_children(self, column_collections=True, **kwargs): > children = Delete.get_children(column_collections, **kwargs) > return children + [self._order_by_clause] > > def _compiler(self, dialect, **kw): > return CustomCompiler(dialect, self, **kw) > > > def delete(table, whereclause = None, **kwargs): > return DeleteOrderBy(table, whereclause, **kwargs) > > > > -- > Tarek Ziadé | http://ziade.org > > -- > 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. > -- 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.