Beispiel #1
0
def _emit_update_statements(base_mapper, uowtransaction, 
                        cached_connections, mapper, table, update):
    """Emit UPDATE statements corresponding to value lists collected
    by _collect_update_commands()."""

    needs_version_id = mapper.version_id_col is not None and \
                table.c.contains_column(mapper.version_id_col)

    def update_stmt():
        clause = sql.and_()

        for col in mapper._pks_by_table[table]:
            clause.clauses.append(col == sql.bindparam(col._label,
                                            type_=col.type))

        if needs_version_id:
            clause.clauses.append(mapper.version_id_col ==\
                    sql.bindparam(mapper.version_id_col._label,
                                    type_=col.type))

        return table.update(clause)

    statement = base_mapper._memo(('update', table), update_stmt)

    rows = 0
    for state, state_dict, params, mapper, \
                connection, value_params in update:

        if value_params:
            c = connection.execute(
                                statement.values(value_params),
                                params)
        else:
            c = cached_connections[connection].\
                                execute(statement, params)

        _postfetch(
                mapper,
                uowtransaction, 
                table, 
                state, 
                state_dict, 
                c.context.prefetch_cols, 
                c.context.postfetch_cols,
                c.context.compiled_parameters[0], 
                value_params)
        rows += c.rowcount

    if connection.dialect.supports_sane_rowcount:
        if rows != len(update):
            raise orm_exc.StaleDataError(
                    "UPDATE statement on table '%s' expected to "
                    "update %d row(s); %d were matched." %
                    (table.description, len(update), rows))

    elif needs_version_id:
        util.warn("Dialect %s does not support updated rowcount "
                "- versioning cannot be verified." % 
                c.dialect.dialect_description,
                stacklevel=12)
Beispiel #2
0
def _emit_delete_statements(base_mapper, uowtransaction, cached_connections, 
                                    mapper, table, delete):
    """Emit DELETE statements corresponding to value lists collected
    by _collect_delete_commands()."""

    need_version_id = mapper.version_id_col is not None and \
        table.c.contains_column(mapper.version_id_col)

    def delete_stmt():
        clause = sql.and_()
        for col in mapper._pks_by_table[table]:
            clause.clauses.append(
                    col == sql.bindparam(col.key, type_=col.type))

        if need_version_id:
            clause.clauses.append(
                mapper.version_id_col == 
                sql.bindparam(
                        mapper.version_id_col.key, 
                        type_=mapper.version_id_col.type
                )
            )

        return table.delete(clause)

    for connection, del_objects in delete.iteritems():
        statement = base_mapper._memo(('delete', table), delete_stmt)
        rows = -1

        connection = cached_connections[connection]

        if need_version_id and \
                not connection.dialect.supports_sane_multi_rowcount:
            # TODO: need test coverage for this [ticket:1761]
            if connection.dialect.supports_sane_rowcount:
                rows = 0
                # execute deletes individually so that versioned
                # rows can be verified
                for params in del_objects:
                    c = connection.execute(statement, params)
                    rows += c.rowcount
            else:
                util.warn(
                    "Dialect %s does not support deleted rowcount "
                    "- versioning cannot be verified." % 
                    connection.dialect.dialect_description,
                    stacklevel=12)
                connection.execute(statement, del_objects)
        else:
            c = connection.execute(statement, del_objects)
            if connection.dialect.supports_sane_multi_rowcount:
                rows = c.rowcount

        if rows != -1 and rows != len(del_objects):
            raise orm_exc.StaleDataError(
                "DELETE statement on table '%s' expected to "
                "delete %d row(s); %d were matched." % 
                (table.description, len(del_objects), c.rowcount)
            )
Beispiel #3
0
    def _run_crud(self, uowcommit, secondary_insert,
                                        secondary_update, secondary_delete):
        connection = uowcommit.transaction.connection(self.mapper)

        if secondary_delete:
            associationrow = secondary_delete[0]
            statement = self.secondary.delete(sql.and_(*[
                                c == sql.bindparam(c.key, type_=c.type)
                                for c in self.secondary.c
                                if c.key in associationrow
                            ]))
            result = connection.execute(statement, secondary_delete)

            if result.supports_sane_multi_rowcount() and \
                        result.rowcount != len(secondary_delete):
                raise exc.StaleDataError(
                        "DELETE statement on table '%s' expected to delete %d row(s); "
                        "Only %d were matched." %
                        (self.secondary.description, len(secondary_delete),
                        result.rowcount)
                    )

        if secondary_update:
            associationrow = secondary_update[0]
            statement = self.secondary.update(sql.and_(*[
                            c == sql.bindparam("old_" + c.key, type_=c.type)
                            for c in self.secondary.c
                            if c.key in associationrow
                        ]))
            result = connection.execute(statement, secondary_update)
            if result.supports_sane_multi_rowcount() and \
                        result.rowcount != len(secondary_update):
                raise exc.StaleDataError(
                        "UPDATE statement on table '%s' expected to update %d row(s); "
                        "Only %d were matched." %
                        (self.secondary.description, len(secondary_update),
                        result.rowcount)
                    )

        if secondary_insert:
            statement = self.secondary.insert()
            connection.execute(statement, secondary_insert)
Beispiel #4
0
 def test_staledata_error_caught(self):
     e = exc.StaleDataError()
     self.assertIsNone(self._decorated_function(1, e))