Code

Opened 3 years ago

Closed 3 years ago

#14849 closed Uncategorized (worksforme)

ManyToManyField has weird behavior in 1.2 w/ multi-db

Reported by: joestump Owned by: nobody
Component: Database layer (models, ORM) Version: 1.2
Severity: Normal Keywords:
Cc: orm, ManyToManyField Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

I've got some code that basically goes like this:

photo = Photo()
photo.tags = tags # List of Tag objects
photo.save()

Photo.tags is a ManyToManyField linked to tags. When I attempt to run this on (1, 2, 3, 'final', 0) I get the following error:

Cannot add "<Tag: girls>": instance is on database "None", value is on database "default"

I assume this has something to do with the fact that the photo I created doesn't have a DB connection associated with it until a DB operation is done. The odd part is that this works just fine on my laptop running version (1, 1, 1, 'final', 0). On 1.2.3, though, I have to do the following:

photo = Photo()
photo.save()
photo.tags = tags
photo.save()

This seems like unexpected behavior.

Attachments (0)

Change History (3)

comment:1 Changed 3 years ago by russellm

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset
  • Resolution set to worksforme
  • Status changed from new to closed

There's something important missing from this report.

The error described ('value is on database "default"') is part of the multi-db machinery, which wasn't added until 1.2.

However, the example as provided wont *ever* work, 1.1 or otherwise:

>>> t1, created = Tag.objects.get_or_create(name='tag1')
>>> t2, created = Tag.objects.get_or_create(name='tag2')

>>> p1 = Photo()
>>> p1.tags = [t1,t2]
ValueError: "'Photo' instance needs to have a primary key value before a many-to-many relationship can be used."

This is the expected behavior -- you can't assign m2m objects until the base object is saved. I've run this test on the tips of the 1.1.X, 1.2.X and trunk branches.

The error you describe is consistent with the cross-database protections kicking in. It's possible that there might have been some changes that have broken these cross-database protections, but we will more details to verify that this is the case -- in particular, any details of your routing setup.

Closing worksforme; feel free to reopen if you can provide a complete test case that reproduces the problem you are seeing.

comment:2 Changed 3 years ago by madtimber

  • Easy pickings unset
  • Resolution worksforme deleted
  • Severity set to Normal
  • Status changed from closed to reopened
  • Type set to Uncategorized
  • UI/UX unset

I've recently gotten this error in production, which runs on EC2/RDS, but never able to reproduce locally.

The separation of the web server and DB in production vs. them together locally seems like a decent starting point for a root cause...

Thinking this should be reviewed a little deeper...thoughts?

comment:3 Changed 3 years ago by julien

  • Resolution set to worksforme
  • Status changed from reopened to closed

Please do not reopen a ticket closed by a core developer (unless, as specifically noted above, you can provide a complete test case). Feel free to bring this issue to the django-dev mailing list for further discussion.

Add Comment

Modify Ticket

Change Properties
<Author field>
Action
as closed
as The resolution will be set. Next status will be 'closed'
The resolution will be deleted. Next status will be 'new'
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.