Opened 7 years ago

Closed 7 years ago

#8062 closed (wontfix)

Re: #7560 casting now breaks filters (ints, bools, floats) in get_db_prep_value

Reported by: magneto Owned by: nobody
Component: Database layer (models, ORM) Version: master
Severity: Keywords:
Cc: django@… Triage Stage: Design decision needed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: UI/UX:


The Changes in r8131 in django/db/models/fields/

to get_db_prep_value for the 'Casted' Field types (Auto, Int, Bool, Decimal, Dates, etc) now really messes with the Filters

for instances, 'searching' where one wants to do a big 'Or' type statment

q = "Some unknown String"
Obj.objects.filter(pk = q) | Obj.objects.filter(name = q) | Obj.objects.filter(other_field = q) 

this will now throw a Value Error in the "pk = q" if the "q" is not an Int ... yes, technically it should be an int, but when build complex queries, with many parameters, 'type checking' everything, in the supposed non-typed language does seem strange.

this, to me is bad form, (for one, 'AutoField' need not just be an Int, but a binary hash or some other unique thing) ..

the data base (because the Query generator actually quotes the input argument) will certain not match non-ints,
i'd also imagine that 'bools' in some DBs can be '1/0, True/False, 'y/n', or just plain 'not 0'

Someone can correct me if i'm wrong, but i'm not sure of any DB today that will throw an error if one tries to match an int column to a string (id = "abc"), so why is this forced type checking here as well?

I do agree that on a "save" event one wants to validate the types, but on a "filter"?

Change History (4)

comment:1 Changed 7 years ago by leosoto

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset

I'll correct you, because in fact, some database interfaces complain if you pass a string when you "ought" to pass an int, for example. So #7560 was about ensuring that db backends get the right types to properly speak with the backing DB interface. Thus, this is not only needed for saves, but also for lookups.

But I think that you are right when you say that this restriction should not propagate to the Django DB-API. Basically, because Django already allows strings on DateFieldand TimeField, for example.

To fix this, each field should have a to_python method which would be called by get_db_prep_save, as it was done on [8143] for DecimalField and what already is on #8101.

comment:2 Changed 7 years ago by jacob

  • Component changed from Uncategorized to Database wrapper
  • Triage Stage changed from Unreviewed to Design decision needed

comment:3 Changed 7 years ago by anonymous

  • Cc django@… added

comment:4 Changed 7 years ago by mtredinnick

  • Resolution set to wontfix
  • Status changed from new to closed

We need to work out what the uniform behaviour is going to be here (after 1.0), however, passing in the right types is actually a good behaviour to get into. Python is not untyped at all. Every piece of data has a well-specified type with clear sematics and '1' + '2' is quite different from 1 + 2, for example. That's why Django's form classes clean the data to the right Python types and your other code should do so as well.

Over time the Python language has also tended towards removing automatic/transparent coercions of data types because it disguised a number of bugs. Django is getting closer to following those semantics as well. As Leo points out, a number of databases (including the latest PostgreSQL releases) do require the correct types to be passed in, or an explicit cast to be used.

Closing as wontfix, since there isn't really a bug here. If there's a genuine use-case where it's impossible to know the right type ahead of time, that can be brought up on a case-by-case basis (in a new ticket), but the general issue here is just a matter of inconvenience caused by type laxity in the past, not a bug.

Note: See TracTickets for help on using tickets.
Back to Top