~ubuntu-branches/debian/jessie/sqlalchemy/jessie

« back to all changes in this revision

Viewing changes to lib/sqlalchemy/orm/dependency.py

  • Committer: Package Import Robot
  • Author(s): Piotr Ożarowski, Jakub Wilk, Piotr Ożarowski
  • Date: 2013-07-06 20:53:52 UTC
  • mfrom: (1.4.23) (16.1.17 experimental)
  • Revision ID: package-import@ubuntu.com-20130706205352-ryppl1eto3illd79
Tags: 0.8.2-1
[ Jakub Wilk ]
* Use canonical URIs for Vcs-* fields.

[ Piotr Ożarowski ]
* New upstream release
* Upload to unstable
* Build depend on python3-all instead of -dev, extensions are not built for
  Python 3.X 

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
# orm/dependency.py
2
 
# Copyright (C) 2005-2012 the SQLAlchemy authors and contributors <see AUTHORS file>
 
2
# Copyright (C) 2005-2013 the SQLAlchemy authors and contributors <see AUTHORS file>
3
3
#
4
4
# This module is part of SQLAlchemy and is released under
5
5
# the MIT License: http://www.opensource.org/licenses/mit-license.php
8
8
 
9
9
"""
10
10
 
11
 
from sqlalchemy import sql, util, exc as sa_exc
12
 
from sqlalchemy.orm import attributes, exc, sync, unitofwork, \
 
11
from .. import sql, util, exc as sa_exc
 
12
from . import attributes, exc, sync, unitofwork, \
13
13
                                        util as mapperutil
14
 
from sqlalchemy.orm.interfaces import ONETOMANY, MANYTOONE, MANYTOMANY
 
14
from .interfaces import ONETOMANY, MANYTOONE, MANYTOMANY
 
15
 
15
16
 
16
17
class DependencyProcessor(object):
17
18
    def __init__(self, prop):
32
33
        if self.passive_updates:
33
34
            self._passive_update_flag = attributes.PASSIVE_NO_INITIALIZE
34
35
        else:
35
 
            self._passive_update_flag= attributes.PASSIVE_OFF
 
36
            self._passive_update_flag = attributes.PASSIVE_OFF
36
37
 
37
38
        self.key = prop.key
38
39
        if not self.prop.synchronize_pairs:
63
64
        """
64
65
        uow.register_preprocessor(self, True)
65
66
 
66
 
 
67
67
    def per_property_flush_actions(self, uow):
68
68
        after_save = unitofwork.ProcessAll(uow, self, False, True)
69
69
        before_delete = unitofwork.ProcessAll(uow, self, True, True)
95
95
                                        before_delete
96
96
                                        )
97
97
 
98
 
 
99
98
    def per_state_flush_actions(self, uow, states, isdelete):
100
99
        """establish actions and dependencies related to a flush.
101
100
 
159
158
            # detect if there's anything changed or loaded
160
159
            # by a preprocessor on this state/attribute.  if not,
161
160
            # we should be able to skip it entirely.
162
 
            sum_ = state.manager[self.key].impl.get_all_pending(state, state.dict)
 
161
            sum_ = state.manager[self.key].impl.get_all_pending(
 
162
                state, state.dict)
163
163
 
164
164
            if not sum_:
165
165
                continue
210
210
                                                after_save, before_delete,
211
211
                                                isdelete, childisdelete)
212
212
 
213
 
 
214
213
    def presort_deletes(self, uowcommit, states):
215
214
        return False
216
215
 
247
246
                self.mapper in uowcommit.mappers
248
247
 
249
248
    def _verify_canload(self, state):
250
 
        if state is not None and \
 
249
        if self.prop.uselist and state is None:
 
250
            raise exc.FlushError(
 
251
                    "Can't flush None value found in "
 
252
                    "collection %s" % (self.prop, ))
 
253
        elif state is not None and \
251
254
            not self.mapper._canload(state,
252
255
                            allow_subtypes=not self.enable_typechecks):
253
256
            if self.mapper._canload(state, allow_subtypes=True):
310
313
    def __repr__(self):
311
314
        return "%s(%s)" % (self.__class__.__name__, self.prop)
312
315
 
 
316
 
313
317
class OneToManyDP(DependencyProcessor):
314
318
 
315
319
    def per_property_dependencies(self, uow, parent_saves,
433
437
                            uowcommit.register_object(child,
434
438
                                    operation="delete", prop=self.prop)
435
439
 
436
 
 
437
 
 
438
440
    def presort_saves(self, uowcommit, states):
439
441
        children_added = uowcommit.memo(('children_added', self), set)
440
442
 
559
561
                            pks_changed):
560
562
        source = state
561
563
        dest = child
 
564
        self._verify_canload(child)
562
565
        if dest is None or \
563
566
                (not self.post_update and uowcommit.is_deleted(dest)):
564
567
            return
565
 
        self._verify_canload(child)
566
568
        if clearkeys:
567
569
            sync.clear(dest, self.mapper, self.prop.synchronize_pairs)
568
570
        else:
577
579
                            self.parent,
578
580
                            self.prop.synchronize_pairs)
579
581
 
 
582
 
580
583
class ManyToOneDP(DependencyProcessor):
581
584
    def __init__(self, prop):
582
585
        DependencyProcessor.__init__(self, prop)
690
693
                            continue
691
694
                        uowcommit.register_object(child, isdelete=True,
692
695
                                        operation="delete", prop=self.prop)
693
 
                        for c, m, st_, dct_ in self.mapper.cascade_iterator(
694
 
                                                            'delete', child):
 
696
                        t = self.mapper.cascade_iterator('delete', child)
 
697
                        for c, m, st_, dct_ in t:
695
698
                            uowcommit.register_object(
696
699
                                st_, isdelete=True)
697
700
 
704
707
                                        self.key,
705
708
                                        self._passive_delete_flag)
706
709
                if history:
707
 
                    ret = True
708
710
                    for child in history.deleted:
709
711
                        if self.hasparent(child) is False:
710
712
                            uowcommit.register_object(child, isdelete=True,
711
713
                                        operation="delete", prop=self.prop)
712
714
 
713
 
                            for c, m, st_, dct_ in self.mapper.cascade_iterator(
714
 
                                                            'delete', child):
715
 
                                uowcommit.register_object(
716
 
                                    st_,
717
 
                                    isdelete=True)
 
715
                            t = self.mapper.cascade_iterator('delete', child)
 
716
                            for c, m, st_, dct_ in t:
 
717
                                uowcommit.register_object(st_, isdelete=True)
718
718
 
719
719
    def process_deletes(self, uowcommit, states):
720
720
        if self.post_update and \
773
773
                            uowcommit,
774
774
                            False)
775
775
 
 
776
 
776
777
class DetectKeySwitch(DependencyProcessor):
777
778
    """For many-to-one relationships with no one-to-many backref,
778
779
    searches for parents through the unit of work when a primary
862
863
                related = state.get_impl(self.key).get(state, dict_,
863
864
                        passive=self._passive_update_flag)
864
865
                if related is not attributes.PASSIVE_NO_RESULT and \
865
 
                    related is not None:
 
866
                        related is not None:
866
867
                    related_state = attributes.instance_state(dict_[self.key])
867
868
                    if related_state in switchers:
868
869
                        uowcommit.register_object(state,
932
933
            ])
933
934
 
934
935
    def presort_deletes(self, uowcommit, states):
 
936
        # TODO: no tests fail if this whole
 
937
        # thing is removed !!!!
935
938
        if not self.passive_deletes:
936
939
            # if no passive deletes, load history on
937
940
            # the collection, so that prop_has_changes()
938
941
            # returns True
939
942
            for state in states:
940
 
                history = uowcommit.get_attribute_history(
 
943
                uowcommit.get_attribute_history(
941
944
                                        state,
942
945
                                        self.key,
943
946
                                        self._passive_delete_flag)
1031
1034
                                                passive)
1032
1035
            if history:
1033
1036
                for child in history.added:
1034
 
                    if child is None or \
1035
 
                            (processed is not None and
 
1037
                    if (processed is not None and
1036
1038
                                (state, child) in processed):
1037
1039
                        continue
1038
1040
                    associationrow = {}
1043
1045
                        continue
1044
1046
                    secondary_insert.append(associationrow)
1045
1047
                for child in history.deleted:
1046
 
                    if child is None or \
1047
 
                            (processed is not None and
 
1048
                    if (processed is not None and
1048
1049
                            (state, child) in processed):
1049
1050
                        continue
1050
1051
                    associationrow = {}
1097
1098
            if result.supports_sane_multi_rowcount() and \
1098
1099
                        result.rowcount != len(secondary_delete):
1099
1100
                raise exc.StaleDataError(
1100
 
                        "DELETE statement on table '%s' expected to delete %d row(s); "
1101
 
                        "Only %d were matched." %
1102
 
                        (self.secondary.description, len(secondary_delete),
1103
 
                        result.rowcount)
1104
 
                    )
 
1101
                    "DELETE statement on table '%s' expected to delete "
 
1102
                    "%d row(s); Only %d were matched." %
 
1103
                    (self.secondary.description, len(secondary_delete),
 
1104
                    result.rowcount)
 
1105
                )
1105
1106
 
1106
1107
        if secondary_update:
1107
1108
            associationrow = secondary_update[0]
1114
1115
            if result.supports_sane_multi_rowcount() and \
1115
1116
                        result.rowcount != len(secondary_update):
1116
1117
                raise exc.StaleDataError(
1117
 
                        "UPDATE statement on table '%s' expected to update %d row(s); "
1118
 
                        "Only %d were matched." %
1119
 
                        (self.secondary.description, len(secondary_update),
1120
 
                        result.rowcount)
1121
 
                    )
 
1118
                    "UPDATE statement on table '%s' expected to update "
 
1119
                    "%d row(s); Only %d were matched." %
 
1120
                    (self.secondary.description, len(secondary_update),
 
1121
                    result.rowcount)
 
1122
                )
1122
1123
 
1123
1124
        if secondary_insert:
1124
1125
            statement = self.secondary.insert()
1126
1127
 
1127
1128
    def _synchronize(self, state, child, associationrow,
1128
1129
                                            clearkeys, uowcommit, operation):
1129
 
        if associationrow is None:
1130
 
            return
 
1130
 
 
1131
        # this checks for None if uselist=True
 
1132
        self._verify_canload(child)
 
1133
 
 
1134
        # but if uselist=False we get here.   If child is None,
 
1135
        # no association row can be generated, so return.
 
1136
        if child is None:
 
1137
            return False
1131
1138
 
1132
1139
        if child is not None and not uowcommit.session._contains_state(child):
1133
1140
            if not child.deleted:
1137
1144
                    (mapperutil.state_class_str(child), operation, self.prop))
1138
1145
            return False
1139
1146
 
1140
 
        self._verify_canload(child)
1141
 
 
1142
1147
        sync.populate_dict(state, self.parent, associationrow,
1143
1148
                                        self.prop.synchronize_pairs)
1144
1149
        sync.populate_dict(child, self.mapper, associationrow,
1154
1159
                            self.prop.synchronize_pairs)
1155
1160
 
1156
1161
_direction_to_processor = {
1157
 
    ONETOMANY : OneToManyDP,
 
1162
    ONETOMANY: OneToManyDP,
1158
1163
    MANYTOONE: ManyToOneDP,
1159
 
    MANYTOMANY : ManyToManyDP,
 
1164
    MANYTOMANY: ManyToManyDP,
1160
1165
}
1161