jmoiron / johnny-cache

johnny cache django caching framework
MIT License
304 stars 84 forks source link

When table(s) are in blacklist don't convert iterator to list - issue with cx_Oracle LOB columns #61

Open trebor74hr opened 10 years ago

trebor74hr commented 10 years ago

Scenario: cx_Oracle + Johnny Cache + django.qs.iterator() + table with CLOB column -> produces error:

ProgrammingError: LOB variable no longer valid after subsequent fetch

(more details http://starship.python.net/crew/atuining/cx_Oracle/html/lobobj.html)

The issue is that cache.py in newfun() converts iterator object to list in line 376:

371                 if hasattr(val, '__iter__'):
372                     #Can't permanently cache lazy iterables without creating
373                     #a cacheable data structure. Note that this makes them
374                     #no longer lazy...
375                     #todo - create a smart iterable wrapper
376  ->                 val = list(val)
377                 if key is not None:
378                     self.cache_backend.set(key, val, settings.MIDDLEWARE_SECONDS, db)
379                 return val

and after the rows are fetched, for all but last row CLOB columns become unreadable producing mentioned error.

Therefore I tried to avoid the issue by puting this table in BLACKLIST but the conversion iterator -> list is done anyway.

Suggestion: do not convert iterator -> list in cases where key is not set, i.e. put "if hasattr" into the "if key is not" block.

dlo commented 10 years ago

That's a pretty good suggestion. I'll have to re-read everything and see why that conversion was being made to begin with. Thanks for bringing this to our attention!