@@ -2140,7 +2140,7 @@ def _init_(attr, entity, name):
21402140 if attr .py_type == float :
21412141 if attr .is_pk : throw (TypeError , 'PrimaryKey attribute %s cannot be of type float' % attr )
21422142 elif attr .is_unique : throw (TypeError , 'Unique attribute %s cannot be of type float' % attr )
2143- if attr .is_volatile and ( attr .is_pk or attr . is_collection ) : throw (TypeError ,
2143+ if attr .is_volatile and attr .is_pk : throw (TypeError ,
21442144 '%s attribute %s cannot be volatile' % (attr .__class__ .__name__ , attr ))
21452145
21462146 if attr .interleave is not None :
@@ -2150,6 +2150,8 @@ def _init_(attr, entity, name):
21502150 '`interleave` option value should be True, False or None. Got: %r' % attr .interleave )
21512151 def linked (attr ):
21522152 reverse = attr .reverse
2153+ if reverse .is_volatile :
2154+ attr .is_volatile = True
21532155 if attr .cascade_delete is None :
21542156 attr .cascade_delete = attr .is_collection and reverse .is_required
21552157 elif attr .cascade_delete :
@@ -2867,7 +2869,7 @@ def prefetch_load_all(attr, objects):
28672869 else :
28682870 phantoms = setdata2 - items
28692871 if setdata2 .added : phantoms -= setdata2 .added
2870- if phantoms : throw (UnrepeatableReadError ,
2872+ if phantoms and not attr . is_volatile : throw (UnrepeatableReadError ,
28712873 'Phantom object %s disappeared from collection %s.%s'
28722874 % (safe_repr (phantoms .pop ()), safe_repr (obj2 ), attr .name ))
28732875 items -= setdata2
@@ -2889,7 +2891,8 @@ def load(attr, obj, items=None):
28892891 assert obj ._status_ not in del_statuses
28902892 setdata = obj ._vals_ .get (attr )
28912893 if setdata is None : setdata = obj ._vals_ [attr ] = SetData ()
2892- elif setdata .is_fully_loaded : return setdata
2894+ elif setdata .is_fully_loaded and not attr .is_volatile :
2895+ return setdata
28932896 entity = attr .entity
28942897 reverse = attr .reverse
28952898 rentity = reverse .entity
@@ -2968,7 +2971,7 @@ def load(attr, obj, items=None):
29682971 else :
29692972 phantoms = setdata2 - items
29702973 if setdata2 .added : phantoms -= setdata2 .added
2971- if phantoms : throw (UnrepeatableReadError ,
2974+ if phantoms and not attr . is_volatile : throw (UnrepeatableReadError ,
29722975 'Phantom object %s disappeared from collection %s.%s'
29732976 % (safe_repr (phantoms .pop ()), safe_repr (obj2 ), attr .name ))
29742977 items -= setdata2
@@ -3125,7 +3128,7 @@ def db_reverse_add(attr, objects, item):
31253128 for obj in objects :
31263129 setdata = obj ._vals_ .get (attr )
31273130 if setdata is None : setdata = obj ._vals_ [attr ] = SetData ()
3128- elif setdata .is_fully_loaded : throw (UnrepeatableReadError ,
3131+ elif setdata .is_fully_loaded and not attr . is_volatile : throw (UnrepeatableReadError ,
31293132 'Phantom object %s appeared in collection %s.%s' % (safe_repr (item ), safe_repr (obj ), attr .name ))
31303133 setdata .add (item )
31313134 def reverse_remove (attr , objects , item , undo_funcs ):
0 commit comments