Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/sqlalchemy/orm/exc.py: 43%

69 statements  

« prev     ^ index     » next       coverage.py v7.0.1, created at 2022-12-25 06:11 +0000

1# orm/exc.py 

2# Copyright (C) 2005-2022 the SQLAlchemy authors and contributors 

3# <see AUTHORS file> 

4# 

5# This module is part of SQLAlchemy and is released under 

6# the MIT License: https://www.opensource.org/licenses/mit-license.php 

7 

8"""SQLAlchemy ORM exceptions.""" 

9from .. import exc as sa_exc 

10from .. import util 

11from ..exc import MultipleResultsFound # noqa 

12from ..exc import NoResultFound # noqa 

13 

14 

15NO_STATE = (AttributeError, KeyError) 

16"""Exception types that may be raised by instrumentation implementations.""" 

17 

18 

19class StaleDataError(sa_exc.SQLAlchemyError): 

20 """An operation encountered database state that is unaccounted for. 

21 

22 Conditions which cause this to happen include: 

23 

24 * A flush may have attempted to update or delete rows 

25 and an unexpected number of rows were matched during 

26 the UPDATE or DELETE statement. Note that when 

27 version_id_col is used, rows in UPDATE or DELETE statements 

28 are also matched against the current known version 

29 identifier. 

30 

31 * A mapped object with version_id_col was refreshed, 

32 and the version number coming back from the database does 

33 not match that of the object itself. 

34 

35 * A object is detached from its parent object, however 

36 the object was previously attached to a different parent 

37 identity which was garbage collected, and a decision 

38 cannot be made if the new parent was really the most 

39 recent "parent". 

40 

41 """ 

42 

43 

44ConcurrentModificationError = StaleDataError 

45 

46 

47class FlushError(sa_exc.SQLAlchemyError): 

48 """A invalid condition was detected during flush().""" 

49 

50 

51class UnmappedError(sa_exc.InvalidRequestError): 

52 """Base for exceptions that involve expected mappings not present.""" 

53 

54 

55class ObjectDereferencedError(sa_exc.SQLAlchemyError): 

56 """An operation cannot complete due to an object being garbage 

57 collected. 

58 

59 """ 

60 

61 

62class DetachedInstanceError(sa_exc.SQLAlchemyError): 

63 """An attempt to access unloaded attributes on a 

64 mapped instance that is detached.""" 

65 

66 code = "bhk3" 

67 

68 

69class UnmappedInstanceError(UnmappedError): 

70 """An mapping operation was requested for an unknown instance.""" 

71 

72 @util.preload_module("sqlalchemy.orm.base") 

73 def __init__(self, obj, msg=None): 

74 base = util.preloaded.orm_base 

75 

76 if not msg: 

77 try: 

78 base.class_mapper(type(obj)) 

79 name = _safe_cls_name(type(obj)) 

80 msg = ( 

81 "Class %r is mapped, but this instance lacks " 

82 "instrumentation. This occurs when the instance " 

83 "is created before sqlalchemy.orm.mapper(%s) " 

84 "was called." % (name, name) 

85 ) 

86 except UnmappedClassError: 

87 msg = _default_unmapped(type(obj)) 

88 if isinstance(obj, type): 

89 msg += ( 

90 "; was a class (%s) supplied where an instance was " 

91 "required?" % _safe_cls_name(obj) 

92 ) 

93 UnmappedError.__init__(self, msg) 

94 

95 def __reduce__(self): 

96 return self.__class__, (None, self.args[0]) 

97 

98 

99class UnmappedClassError(UnmappedError): 

100 """An mapping operation was requested for an unknown class.""" 

101 

102 def __init__(self, cls, msg=None): 

103 if not msg: 

104 msg = _default_unmapped(cls) 

105 UnmappedError.__init__(self, msg) 

106 

107 def __reduce__(self): 

108 return self.__class__, (None, self.args[0]) 

109 

110 

111class ObjectDeletedError(sa_exc.InvalidRequestError): 

112 """A refresh operation failed to retrieve the database 

113 row corresponding to an object's known primary key identity. 

114 

115 A refresh operation proceeds when an expired attribute is 

116 accessed on an object, or when :meth:`_query.Query.get` is 

117 used to retrieve an object which is, upon retrieval, detected 

118 as expired. A SELECT is emitted for the target row 

119 based on primary key; if no row is returned, this 

120 exception is raised. 

121 

122 The true meaning of this exception is simply that 

123 no row exists for the primary key identifier associated 

124 with a persistent object. The row may have been 

125 deleted, or in some cases the primary key updated 

126 to a new value, outside of the ORM's management of the target 

127 object. 

128 

129 """ 

130 

131 @util.preload_module("sqlalchemy.orm.base") 

132 def __init__(self, state, msg=None): 

133 base = util.preloaded.orm_base 

134 

135 if not msg: 

136 msg = ( 

137 "Instance '%s' has been deleted, or its " 

138 "row is otherwise not present." % base.state_str(state) 

139 ) 

140 

141 sa_exc.InvalidRequestError.__init__(self, msg) 

142 

143 def __reduce__(self): 

144 return self.__class__, (None, self.args[0]) 

145 

146 

147class UnmappedColumnError(sa_exc.InvalidRequestError): 

148 """Mapping operation was requested on an unknown column.""" 

149 

150 

151class LoaderStrategyException(sa_exc.InvalidRequestError): 

152 """A loader strategy for an attribute does not exist.""" 

153 

154 def __init__( 

155 self, 

156 applied_to_property_type, 

157 requesting_property, 

158 applies_to, 

159 actual_strategy_type, 

160 strategy_key, 

161 ): 

162 if actual_strategy_type is None: 

163 sa_exc.InvalidRequestError.__init__( 

164 self, 

165 "Can't find strategy %s for %s" 

166 % (strategy_key, requesting_property), 

167 ) 

168 else: 

169 sa_exc.InvalidRequestError.__init__( 

170 self, 

171 'Can\'t apply "%s" strategy to property "%s", ' 

172 'which is a "%s"; this loader strategy is intended ' 

173 'to be used with a "%s".' 

174 % ( 

175 util.clsname_as_plain_name(actual_strategy_type), 

176 requesting_property, 

177 util.clsname_as_plain_name(applied_to_property_type), 

178 util.clsname_as_plain_name(applies_to), 

179 ), 

180 ) 

181 

182 

183def _safe_cls_name(cls): 

184 try: 

185 cls_name = ".".join((cls.__module__, cls.__name__)) 

186 except AttributeError: 

187 cls_name = getattr(cls, "__name__", None) 

188 if cls_name is None: 

189 cls_name = repr(cls) 

190 return cls_name 

191 

192 

193@util.preload_module("sqlalchemy.orm.base") 

194def _default_unmapped(cls): 

195 base = util.preloaded.orm_base 

196 

197 try: 

198 mappers = base.manager_of_class(cls).mappers 

199 except (TypeError,) + NO_STATE: 

200 mappers = {} 

201 name = _safe_cls_name(cls) 

202 

203 if not mappers: 

204 return "Class '%s' is not mapped" % name