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.

Reply via email to