Code

Opened 5 years ago

Closed 5 years ago

#10634 closed (invalid)

Confusing differential exceptions: get_or_create vs get with psycopg2

Reported by: fergusferrier Owned by: nobody
Component: Database layer (models, ORM) Version: master
Severity: Keywords: psycopg2 get_or_create get misleading
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: UI/UX:

Description

I'm using Psycopg2. I hope the models here are somewhat self-explanatory in structure.

I made the simple mistake of forgetting the boolean 'created' in a get_or_create...

   usr = EventsUser.objects.get_or_create(user = request.user)

Then running the following code [NB. usr is not an instance of EventsUser at this point]...

Reminder.objects.get_or_create(
    events_user = usr,
    event = event,
    assoctype = 'EML_HR'
)

gives thus:

Traceback (most recent call last):
  File "/home/django/domains/staging.mypidge.com/project/Apps/Events/tests/views.py", line 418, in test_set_reminder_unset
    response = self.client.get(reverse('Events.views.SetReminders', args=[self.event.id]), {'day': '1', 'hour': '1'})
  File "/home/django/domains/mypidge.com/env/lib/python2.5/site-packages/django/test/client.py", line 278, in get
    response = self.request(**r)
  File "/home/django/domains/mypidge.com/env/lib/python2.5/site-packages/django/core/handlers/base.py", line 91, in get_response
    response = callback(request, *callback_args, **callback_kwargs)
  File "/home/django/domains/staging.mypidge.com/project/Apps/basic/funcs.py", line 35, in decorator
    return f(request, *args, **kwargs)
  File "/home/django/domains/staging.mypidge.com/project/Apps/Events/views.py", line 319, in SetReminders
    assoctype = 'EML_HR'
  File "/home/django/domains/mypidge.com/env/lib/python2.5/site-packages/django/db/models/manager.py", line 120, in get_or_create
    return self.get_query_set().get_or_create(**kwargs)
  File "/home/django/domains/mypidge.com/env/lib/python2.5/site-packages/django/db/models/query.py", line 365, in get_or_create
    return self.get(**kwargs), False
  File "/home/django/domains/mypidge.com/env/lib/python2.5/site-packages/django/db/models/query.py", line 337, in get
    num = len(clone)
  File "/home/django/domains/mypidge.com/env/lib/python2.5/site-packages/django/db/models/query.py", line 161, in __len__
    self._result_cache = list(self.iterator())
  File "/home/django/domains/mypidge.com/env/lib/python2.5/site-packages/django/db/models/query.py", line 281, in iterator
    for row in self.query.results_iter():
  File "/home/django/domains/mypidge.com/env/lib/python2.5/site-packages/django/db/models/sql/query.py", line 256, in results_iter
    for rows in self.execute_sql(MULTI):
  File "/home/django/domains/mypidge.com/env/lib/python2.5/site-packages/django/db/models/sql/query.py", line 2098, in execute_sql
    cursor.execute(sql, params)
  File "build/bdist.linux-x86_64/egg/psycopg2/extensions.py", line 96, in getquoted
    pobjs = [adapt(o) for o in self._seq]
ProgrammingError: can't adapt

When one replaces the second get_or_create with a plain get, you are returned

    ValueError: Cannot assign "(<EventsUser: EventsUser object>, False)": "Reminder.events_user" must be a "EventsUser" instance.

which is a much more useful exception. I would expect get_or_create to return a similar.

Attachments (0)

Change History (1)

comment:1 Changed 5 years ago by jacob

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

You're passing the wrong type (a 2-tuple) into the database binding, so you're getting a database error. If we typecheck everything coming in we're going to make queries slower, so this is a "you need to get it right in your own code" situation.

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.