Ejemplo n.º 1
0
def _collect_post_update_commands(base_mapper, uowtransaction, table, 
                        states_to_update, post_update_cols):
    """Identify sets of values to use in UPDATE statements for a
    list of states within a post_update operation.

    """

    update = []
    for state, state_dict, mapper, connection in states_to_update:
        if table not in mapper._pks_by_table:
            continue
        pks = mapper._pks_by_table[table]
        params = {}
        hasdata = False

        for col in mapper._cols_by_table[table]:
            if col in pks:
                params[col._label] = \
                        mapper._get_state_attr_by_column(
                                        state,
                                        state_dict, col)
            elif col in post_update_cols:
                prop = mapper._columntoproperty[col]
                history = attributes.get_state_history(
                            state, prop.key, 
                            attributes.PASSIVE_NO_INITIALIZE)
                if history.added:
                    value = history.added[0]
                    params[col.key] = value
                    hasdata = True
        if hasdata:
            update.append((state, state_dict, params, mapper, 
                            connection))
    return update
Ejemplo n.º 2
0
def _collect_post_update_commands(base_mapper, uowtransaction, table, states_to_update, post_update_cols):
    """Identify sets of values to use in UPDATE statements for a
    list of states within a post_update operation.

    """

    update = []
    for state, state_dict, mapper, connection in states_to_update:
        if table not in mapper._pks_by_table:
            continue
        pks = mapper._pks_by_table[table]
        params = {}
        hasdata = False

        for col in mapper._cols_by_table[table]:
            if col in pks:
                params[col._label] = mapper._get_state_attr_by_column(state, state_dict, col)
            elif col in post_update_cols:
                prop = mapper._columntoproperty[col]
                history = attributes.get_state_history(state, prop.key, attributes.PASSIVE_NO_INITIALIZE)
                if history.added:
                    value = history.added[0]
                    params[col.key] = value
                    hasdata = True
        if hasdata:
            update.append((state, state_dict, params, mapper, connection))
    return update
Ejemplo n.º 3
0
    def get_attribute_history(self, state, key, passive=True):
        hashkey = ("history", state, key)

        # cache the objects, not the states; the strong reference here
        # prevents newly loaded objects from being dereferenced during the
        # flush process
        if hashkey in self.attributes:
            (history, cached_passive) = self.attributes[hashkey]
            # if the cached lookup was "passive" and now we want non-passive, do a non-passive
            # lookup and re-cache
            if cached_passive and not passive:
                history = attributes.get_state_history(state, key, passive=False)
                self.attributes[hashkey] = (history, passive)
        else:
            history = attributes.get_state_history(state, key, passive=passive)
            self.attributes[hashkey] = (history, passive)

        if not history or not state.get_impl(key).uses_objects:
            return history
        else:
            return history.as_state()
Ejemplo n.º 4
0
    def get_attribute_history(self, state, key, passive=True):
        hashkey = ("history", state, key)

        # cache the objects, not the states; the strong reference here
        # prevents newly loaded objects from being dereferenced during the
        # flush process
        if hashkey in self.attributes:
            (history, cached_passive) = self.attributes[hashkey]
            # if the cached lookup was "passive" and now we want non-passive, do a non-passive
            # lookup and re-cache
            if cached_passive and not passive:
                history = attributes.get_state_history(state, key, passive=False)
                self.attributes[hashkey] = (history, passive)
        else:
            history = attributes.get_state_history(state, key, passive=passive)
            self.attributes[hashkey] = (history, passive)

        if not history or not state.get_impl(key).uses_objects:
            return history
        else:
            return history.as_state()
Ejemplo n.º 5
0
    def test_history(self):
        for base in (object, MyBaseClass, MyClass):
            class Foo(base):
                pass
            class Bar(base):
                pass

            attributes.register_class(Foo)
            attributes.register_class(Bar)
            attributes.register_attribute(Foo, "name", uselist=False, useobject=False)
            attributes.register_attribute(Foo, "bars", uselist=True, trackparent=True, useobject=True)
            attributes.register_attribute(Bar, "name", uselist=False, useobject=False)


            f1 = Foo()
            f1.name = 'f1'

            eq_(attributes.get_state_history(attributes.instance_state(f1), 'name'), (['f1'], (), ()))

            b1 = Bar()
            b1.name = 'b1'
            f1.bars.append(b1)
            eq_(attributes.get_state_history(attributes.instance_state(f1), 'bars'), ([b1], [], []))

            attributes.instance_state(f1).commit_all(attributes.instance_dict(f1))
            attributes.instance_state(b1).commit_all(attributes.instance_dict(b1))

            eq_(attributes.get_state_history(attributes.instance_state(f1), 'name'), ((), ['f1'], ()))
            eq_(attributes.get_state_history(attributes.instance_state(f1), 'bars'), ((), [b1], ()))

            f1.name = 'f1mod'
            b2 = Bar()
            b2.name = 'b2'
            f1.bars.append(b2)
            eq_(attributes.get_state_history(attributes.instance_state(f1), 'name'), (['f1mod'], (), ['f1']))
            eq_(attributes.get_state_history(attributes.instance_state(f1), 'bars'), ([b2], [b1], []))
            f1.bars.remove(b1)
            eq_(attributes.get_state_history(attributes.instance_state(f1), 'bars'), ([b2], [], [b1]))
    def test_history(self):
        for base in (object, MyBaseClass, MyClass):
            class Foo(base):
                pass
            class Bar(base):
                pass

            attributes.register_class(Foo)
            attributes.register_class(Bar)
            attributes.register_attribute(Foo, "name", uselist=False, useobject=False)
            attributes.register_attribute(Foo, "bars", uselist=True, trackparent=True, useobject=True)
            attributes.register_attribute(Bar, "name", uselist=False, useobject=False)


            f1 = Foo()
            f1.name = 'f1'

            eq_(attributes.get_state_history(attributes.instance_state(f1), 'name'), (['f1'], (), ()))

            b1 = Bar()
            b1.name = 'b1'
            f1.bars.append(b1)
            eq_(attributes.get_state_history(attributes.instance_state(f1), 'bars'), ([b1], [], []))

            attributes.instance_state(f1).commit_all(attributes.instance_dict(f1))
            attributes.instance_state(b1).commit_all(attributes.instance_dict(b1))

            eq_(attributes.get_state_history(attributes.instance_state(f1), 'name'), ((), ['f1'], ()))
            eq_(attributes.get_state_history(attributes.instance_state(f1), 'bars'), ((), [b1], ()))

            f1.name = 'f1mod'
            b2 = Bar()
            b2.name = 'b2'
            f1.bars.append(b2)
            eq_(attributes.get_state_history(attributes.instance_state(f1), 'name'), (['f1mod'], (), ['f1']))
            eq_(attributes.get_state_history(attributes.instance_state(f1), 'bars'), ([b2], [b1], []))
            f1.bars.remove(b1)
            eq_(attributes.get_state_history(attributes.instance_state(f1), 'bars'), ([b2], [], [b1]))
Ejemplo n.º 7
0
    def test_history(self):
        for base in (object, MyBaseClass, MyClass):

            class Foo(base):
                pass

            class Bar(base):
                pass

            register_class(Foo)
            register_class(Bar)
            attributes.register_attribute(Foo,
                                          "name",
                                          uselist=False,
                                          useobject=False)
            attributes.register_attribute(Foo,
                                          "bars",
                                          uselist=True,
                                          trackparent=True,
                                          useobject=True)
            attributes.register_attribute(Bar,
                                          "name",
                                          uselist=False,
                                          useobject=False)

            f1 = Foo()
            f1.name = "f1"

            eq_(
                attributes.get_state_history(attributes.instance_state(f1),
                                             "name"),
                (["f1"], (), ()),
            )

            b1 = Bar()
            b1.name = "b1"
            f1.bars.append(b1)
            eq_(
                attributes.get_state_history(attributes.instance_state(f1),
                                             "bars"),
                ([b1], [], []),
            )

            attributes.instance_state(f1)._commit_all(
                attributes.instance_dict(f1))
            attributes.instance_state(b1)._commit_all(
                attributes.instance_dict(b1))

            eq_(
                attributes.get_state_history(attributes.instance_state(f1),
                                             "name"),
                ((), ["f1"], ()),
            )
            eq_(
                attributes.get_state_history(attributes.instance_state(f1),
                                             "bars"),
                ((), [b1], ()),
            )

            f1.name = "f1mod"
            b2 = Bar()
            b2.name = "b2"
            f1.bars.append(b2)
            eq_(
                attributes.get_state_history(attributes.instance_state(f1),
                                             "name"),
                (["f1mod"], (), ["f1"]),
            )
            eq_(
                attributes.get_state_history(attributes.instance_state(f1),
                                             "bars"),
                ([b2], [b1], []),
            )
            f1.bars.remove(b1)
            eq_(
                attributes.get_state_history(attributes.instance_state(f1),
                                             "bars"),
                ([b2], [], [b1]),
            )
Ejemplo n.º 8
0
def _collect_update_commands(base_mapper, uowtransaction, table, states_to_update):
    """Identify sets of values to use in UPDATE statements for a
    list of states.

    This function works intricately with the history system
    to determine exactly what values should be updated
    as well as how the row should be matched within an UPDATE
    statement.  Includes some tricky scenarios where the primary
    key of an object might have been changed.

    """

    update = []
    for state, state_dict, mapper, connection, has_identity, instance_key, row_switch in states_to_update:
        if table not in mapper._pks_by_table:
            continue

        pks = mapper._pks_by_table[table]

        params = {}
        value_params = {}

        hasdata = hasnull = False
        for col in mapper._cols_by_table[table]:
            if col is mapper.version_id_col:
                params[col._label] = mapper._get_committed_state_attr_by_column(
                    row_switch or state, row_switch and row_switch.dict or state_dict, col
                )

                prop = mapper._columntoproperty[col]
                history = attributes.get_state_history(state, prop.key, attributes.PASSIVE_NO_INITIALIZE)
                if history.added:
                    params[col.key] = history.added[0]
                    hasdata = True
                else:
                    params[col.key] = mapper.version_id_generator(params[col._label])

                    # HACK: check for history, in case the
                    # history is only
                    # in a different table than the one
                    # where the version_id_col is.
                    for prop in mapper._columntoproperty.values():
                        history = attributes.get_state_history(state, prop.key, attributes.PASSIVE_NO_INITIALIZE)
                        if history.added:
                            hasdata = True
            else:
                prop = mapper._columntoproperty[col]
                history = attributes.get_state_history(state, prop.key, attributes.PASSIVE_NO_INITIALIZE)
                if history.added:
                    if isinstance(history.added[0], sql.ClauseElement):
                        value_params[col] = history.added[0]
                    else:
                        value = history.added[0]
                        params[col.key] = value

                    if col in pks:
                        if history.deleted and not row_switch:
                            # if passive_updates and sync detected
                            # this was a  pk->pk sync, use the new
                            # value to locate the row, since the
                            # DB would already have set this
                            if ("pk_cascaded", state, col) in uowtransaction.attributes:
                                value = history.added[0]
                                params[col._label] = value
                            else:
                                # use the old value to
                                # locate the row
                                value = history.deleted[0]
                                params[col._label] = value
                            hasdata = True
                        else:
                            # row switch logic can reach us here
                            # remove the pk from the update params
                            # so the update doesn't
                            # attempt to include the pk in the
                            # update statement
                            del params[col.key]
                            value = history.added[0]
                            params[col._label] = value
                        if value is None:
                            hasnull = True
                    else:
                        hasdata = True
                elif col in pks:
                    value = state.manager[prop.key].impl.get(state, state_dict)
                    if value is None:
                        hasnull = True
                    params[col._label] = value
        if hasdata:
            if hasnull:
                raise sa_exc.FlushError("Can't update table " "using NULL for primary " "key value")
            update.append((state, state_dict, params, mapper, connection, value_params))
    return update
Ejemplo n.º 9
0
def _collect_update_commands(base_mapper, uowtransaction, 
                                table, states_to_update):
    """Identify sets of values to use in UPDATE statements for a
    list of states.
    
    This function works intricately with the history system
    to determine exactly what values should be updated
    as well as how the row should be matched within an UPDATE
    statement.  Includes some tricky scenarios where the primary
    key of an object might have been changed.

    """

    update = []
    for state, state_dict, mapper, connection, has_identity, \
                    instance_key, row_switch in states_to_update:
        if table not in mapper._pks_by_table:
            continue

        pks = mapper._pks_by_table[table]

        params = {}
        value_params = {}

        hasdata = hasnull = False
        for col in mapper._cols_by_table[table]:
            if col is mapper.version_id_col:
                params[col._label] = \
                    mapper._get_committed_state_attr_by_column(
                                    row_switch or state, 
                                    row_switch and row_switch.dict 
                                                or state_dict,
                                    col)

                prop = mapper._columntoproperty[col]
                history = attributes.get_state_history(
                    state, prop.key, 
                    attributes.PASSIVE_NO_INITIALIZE
                )
                if history.added:
                    params[col.key] = history.added[0]
                    hasdata = True
                else:
                    params[col.key] = mapper.version_id_generator(
                                                params[col._label])

                    # HACK: check for history, in case the 
                    # history is only
                    # in a different table than the one 
                    # where the version_id_col is.
                    for prop in mapper._columntoproperty.itervalues():
                        history = attributes.get_state_history(
                                state, prop.key, 
                                attributes.PASSIVE_NO_INITIALIZE)
                        if history.added:
                            hasdata = True
            else:
                prop = mapper._columntoproperty[col]
                history = attributes.get_state_history(
                                state, prop.key, 
                                attributes.PASSIVE_NO_INITIALIZE)
                if history.added:
                    if isinstance(history.added[0],
                                    sql.ClauseElement):
                        value_params[col] = history.added[0]
                    else:
                        value = history.added[0]
                        params[col.key] = value

                    if col in pks:
                        if history.deleted and \
                            not row_switch:
                            # if passive_updates and sync detected
                            # this was a  pk->pk sync, use the new
                            # value to locate the row, since the
                            # DB would already have set this
                            if ("pk_cascaded", state, col) in \
                                            uowtransaction.attributes:
                                value = history.added[0]
                                params[col._label] = value
                            else:
                                # use the old value to 
                                # locate the row
                                value = history.deleted[0]
                                params[col._label] = value
                            hasdata = True
                        else:
                            # row switch logic can reach us here
                            # remove the pk from the update params
                            # so the update doesn't
                            # attempt to include the pk in the
                            # update statement
                            del params[col.key]
                            value = history.added[0]
                            params[col._label] = value
                        if value is None:
                            hasnull = True
                    else:
                        hasdata = True
                elif col in pks:
                    value = state.manager[prop.key].impl.get(
                                                    state, state_dict)
                    if value is None:
                        hasnull = True
                    params[col._label] = value
        if hasdata:
            if hasnull:
                raise sa_exc.FlushError(
                            "Can't update table "
                            "using NULL for primary "
                            "key value")
            update.append((state, state_dict, params, mapper, 
                            connection, value_params))
    return update
Ejemplo n.º 10
0
    def test_history(self):
        for base in (object, MyBaseClass, MyClass):

            class Foo(base):
                pass

            class Bar(base):
                pass

            register_class(Foo)
            register_class(Bar)
            attributes.register_attribute(
                Foo, "name", uselist=False, useobject=False
            )
            attributes.register_attribute(
                Foo, "bars", uselist=True, trackparent=True, useobject=True
            )
            attributes.register_attribute(
                Bar, "name", uselist=False, useobject=False
            )

            f1 = Foo()
            f1.name = "f1"

            eq_(
                attributes.get_state_history(
                    attributes.instance_state(f1), "name"
                ),
                (["f1"], (), ()),
            )

            b1 = Bar()
            b1.name = "b1"
            f1.bars.append(b1)
            eq_(
                attributes.get_state_history(
                    attributes.instance_state(f1), "bars"
                ),
                ([b1], [], []),
            )

            attributes.instance_state(f1)._commit_all(
                attributes.instance_dict(f1)
            )
            attributes.instance_state(b1)._commit_all(
                attributes.instance_dict(b1)
            )

            eq_(
                attributes.get_state_history(
                    attributes.instance_state(f1), "name"
                ),
                ((), ["f1"], ()),
            )
            eq_(
                attributes.get_state_history(
                    attributes.instance_state(f1), "bars"
                ),
                ((), [b1], ()),
            )

            f1.name = "f1mod"
            b2 = Bar()
            b2.name = "b2"
            f1.bars.append(b2)
            eq_(
                attributes.get_state_history(
                    attributes.instance_state(f1), "name"
                ),
                (["f1mod"], (), ["f1"]),
            )
            eq_(
                attributes.get_state_history(
                    attributes.instance_state(f1), "bars"
                ),
                ([b2], [b1], []),
            )
            f1.bars.remove(b1)
            eq_(
                attributes.get_state_history(
                    attributes.instance_state(f1), "bars"
                ),
                ([b2], [], [b1]),
            )