Closed
Description
Migrated issue, originally created by Anonymous
I've noticed a small problem going from 0.5.5 to 0.6.6 which the attached unit test should illustrate. It runs without errors on 0.5.5 but the first test errors out on 0.6.6. The second test shows a workaround. No biggie but curious, I think. Here's the output when running this test:
sas% python test_sa66.py
sqlalchemy.version: 0.5.5
..
----------------------------------------------------------------------
Ran 2 tests in 0.031s
OK
sas% python test_sa66.py
sqlalchemy.version: 0.6.6
F.
======================================================================
FAIL: test_01_failing_on_sa66 (__main__.Test)
----------------------------------------------------------------------
Traceback (most recent call last):
File "test_sa66.py", line 30, in test_01_failing_on_sa66
self.assertEqual(1, self.db.m2m.count())
AssertionError: 1 != 0
----------------------------------------------------------------------
Ran 2 tests in 0.033s
FAILED (failures=1)
Attachments: test_sa66.py
Metadata
Metadata
Assignees
Labels
Type
Projects
Relationships
Development
No branches or pull requests
Activity
sqlalchemy-bot commentedon Feb 10, 2011
Anonymous wrote:
Bugger, I wanted to CC myself but turns out I can't modify after submission :) Here's my address;
sas@abstracture.de
if you'd be so kind and add it. Thanks!sqlalchemy-bot commentedon Feb 10, 2011
Michael Bayer (@zzzeek) wrote:
OK well, yeah, nothing has actually "changed" in SQLA since 0.5 regarding what happens here, its a garbage collection artifact allowing it to work in 0.5. If I do this to 0.5:
it fails there too.
Will poke around and see if we can find some way to keep obj() (in this case it's your MappedFoo) from falling out of scope while its receiving an append event, though that suggests artificially creating a reference, always dangerous.
sqlalchemy-bot commentedon Feb 10, 2011
Changes by Michael Bayer (@zzzeek):
sqlalchemy-bot commentedon Feb 10, 2011
Michael Bayer (@zzzeek) wrote:
OK thanks for reporting this I'm happy with the solution which is to raise an exception for this condition. It's a warning in 0.6 to ensure existing code that "works" regardless continues to run.
e155b7b
036d2c1
sqlalchemy-bot commentedon Feb 10, 2011
Changes by Michael Bayer (@zzzeek):
sqlalchemy-bot commentedon Feb 10, 2011
Michael Bayer (@zzzeek) wrote:
that should be d8aa338 for the 0.6 branch.
sqlalchemy-bot commentedon Feb 10, 2011
Changes by Michael Bayer (@zzzeek):
sqlalchemy-bot commentedon Feb 10, 2011
Anonymous wrote:
Thanks for the quick response and fix! Just to understand the implications, you're saying (in CHANGES) that
should fail, because in this rare case append is sent to an already dereferenced parent object. I suppose the 'proper' way to write this is then
as I did in my work-around. I usually don't chain calls like that anyway but I'm still surprised that 'chaining' vs 'not-chaining' behaves in such a fundamentally different way. Is this due to the way mapped objects work? I wouldn't have expected anything to be garbage collectable on that line (but then again I don't know much about the details of SQLAlchemy).
Just curious to understand what's happening :)
sqlalchemy-bot commentedon Feb 10, 2011
Michael Bayer (@zzzeek) wrote:
Replying to guest:
nothing to do with SQLAlchemy, except that SQLA needs a reference to the parent object when an append occurs.
You can try this at home!
output:
The "foo is gc'ed" message prints before the "append" message does - Foo is gone by the time you're appending. If anything, the fact that this also happens with SQLA is because we've worked so hard to not get in the way of normal Python gc behavior ;)
sqlalchemy-bot commentedon Feb 10, 2011
Anonymous wrote:
Oh, I see, it never occurred to me that first() returns a new object that's not being referenced. In my mind it was more akin to foo0, i.e. a reference to an object retained elsewhere. Thanks for clearing that up!