How to determine the maximum integer the model can handle? - django

"What is the biggest integer the model field that this application instance can handle?"
We have sys.maxint, but I'm looking for the database+model instance. We have the IntegerField, the SmallIntegerField, the PositiveSmallIntegerField, and a couple of others beside. They could all vary between each other and each database type.
I found the "IntegerRangeField" custom field example here on stackoverflow. Might have to use that, and guess the lowest common denominator? Or rethink the design I suppose.
Is there an easy way to work out the biggest integer an IntegerField, or its variants, can cope with?

It depends on your database backend.
Use ./manage.py sql your_app_name to check generated types for your DB-columns, and look through your database documentation for type ranges.
For MySQL: http://dev.mysql.com/doc/refman/5.1/en/numeric-types.html
For PostgreSQL: http://www.postgresql.org/docs/8.1/static/datatype.html#DATATYPE-TABLE

Can't be easily done. Just set a constant and use that.
MAX_SMALL_INT = 32767
position = models.PositiveSmallIntegerField(default=MAX_SMALL_INT)

Related

Best index for a Django model when filtering on one field and ordering on another field

I use Django 2.2 linked to PostgreSQL and would like to optimise my database queries.
Given the following simplified model:
class Person(model.Models):
name = models.CharField()
age = models.Integerfield()
on which I have to do the following query, say,
Person.objects.filter(age__gt=20, age__lt=30).order_by('name')
What would be the best way to define the index in the model Meta field so as to optimise the query?
Which of these four options would be best?
class Meta
indexes = [models.Index(fields=['age','name']),
models.Index(fields=['name','age']),
models.Index(fields=['name']),
models.Index(fields=['age'])]
Is it, for example, possible to prevent sorting when the query is done? Thank you.
This is really a postgres question, as much as a Django question, right?
I think there is a good chance that creating an index on your sort field will help with performance. But there are a lot of caveats and if it's really important to you, you might want to do some testing focused on Postgres (ie, just run some queries in psql and see what happens). Some caveats include:
it might depend on which type of index is created for you by Django
Postgres, of course, does not always use index anyway when running a query but it should if you've got the right one and the right query (and if there is enough data in the table to justify loading the index)
it might matter how your SELECT is formatted by Django
I suggest you create your model and specify that you want the index. Then use Django Debug Toolbar to find out what SELECT query is really getting run. Then, open a dbshell with manage.py dbshell (aka psql) and run ANALYZE with that same select. Assuming you can interpret the output, you will see for yourself whether your index is coming in to play. Paste the ANALYZE output here, if you like.
According to this Postgres documentation ORDER BY can be assisted by a btree index. The b-tree type of index is what Django will create for you by default.
So, why don't you try this:
class Meta:
indexes = [models.Index(fields=['age', 'name'])]
Then go run an EXPLAIN ANALYZE in dbshell and see whether it worked.
# You should apply indexing on age, because you are searching for 'age' column data
indexes = [
models.Index(fields=['age'])
]

What is the default range for IntegerFields on Django?

Such a simple question, but can't seem to find anything in the documentation about it.
For example, can integers be negative?
There is none. Any integer is valid. Negative is definitely fine. But the IntegerField is not limited by default. #16747 closed Bug (wontfix) IntegerField could validate too large numbers to work with PostgreSQL and MySQL be default was a request to fix this, but it was denied.
Keep in mind that an IntegerField is not necessarily connected to a particular database field. It usually is, in which case the recommendation is to add max_value and min_value to match your database field requirements.
If you're talking about models.IntegerField then there is indeed a range for that and it is mentioned in the documentation.
An integer. Values from -2147483648 to 2147483647 are safe in all
databases supported by Django.
It uses MinValueValidator and MaxValueValidator to validate the input
based on the values that the default database supports.
If you're talking about forms.IntegerField, then the only way to validate it is to pass a parameter of max_value and min_value for that.
Validates that the given value is an integer. Uses MaxValueValidator
and MinValueValidator if max_value and min_value are provided.

Difference between PositiveInteger and PositiveSmallInteger Field in Django

There is no difference between PositiveInteger and PositiveSmallInteger field in the Django source code. But, Django documentation says,
PositiveInteger starts from 0 to 2147483647 and PositiveSmallInteger starts from 0 to 32767.
Please clarify me what is the difference between these two types.
Thanks in advance.
This is one of those things that is the way it is because it got that way.
Django supports SmallIntegerField because Django grew up on PostgreSQL, and PostgreSQL supports smallint. The PosgreSQL docs say
The smallint type is generally only used if disk space is at a premium.
Also there's a difference in the code if you check the backends of Django. There you see it uses the SMALLINT feature on some databases, for example sqlite.
...
class FlexibleFieldLookupDict:
# Maps SQL types to Django Field types. Some of the SQL types have multiple
# entries here because SQLite allows for anything and doesn't normalize the
# field type; it uses whatever was given.
base_data_types_reverse = {
'bool': 'BooleanField',
'boolean': 'BooleanField',
'smallint': 'SmallIntegerField',
'smallint unsigned': 'PositiveSmallIntegerField',
'smallinteger': 'SmallIntegerField',
'int': 'IntegerField',
'integer': 'IntegerField',
'bigint': 'BigIntegerField',
'integer unsigned': 'PositiveIntegerField',
'decimal': 'DecimalField',
'real': 'FloatField',
...

Django storing mobile number, what field to use?

In my models I need to store a mobile number in the following format 447182716281. What field should I use? Does Django have anything to support this?
example
mobile = models.IntegerField(max_length=12)
Phone numbers must be CharFields. Integer field will not preserve leading 0, +, and spacing.
I think is a interesting question since it really depends on the problem modeling, CharField works fine, but have a look at this:
ORM tricks
There is a regex field in form validation. In model use just CharField.
On using models.IntegerField(default=0)
for larger number it gives error
Ensure this value is less than or equal to 2147483647.
So better way to use would be.
BigIntegerField
A 64-bit integer, much like an IntegerField except that it is guaranteed to fit numbers from -9223372036854775808 to 9223372036854775807. The default form widget for this field is a TextInput.
with PostgreSQL IntegerField is not working properly so it's better to use CharField with Django.
Number=models.CharField(max_length=12)

How to limit columns returned by Django query?

That seems simple enough, but all Django Queries seems to be 'SELECT *'
How do I build a query returning only a subset of fields ?
In Django 1.1 onwards, you can use defer('col1', 'col2') to exclude columns from the query, or only('col1', 'col2') to only get a specific set of columns. See the documentation.
values does something slightly different - it only gets the columns you specify, but it returns a list of dictionaries rather than a set of model instances.
Append a .values("column1", "column2", ...) to your query
The accepted answer advising defer and only which the docs discourage in most cases.
only use defer() when you cannot, at queryset load time, determine if you will need the extra fields or not. If you are frequently loading and using a particular subset of your data, the best choice you can make is to normalize your models and put the non-loaded data into a separate model (and database table). If the columns must stay in the one table for some reason, create a model with Meta.managed = False (see the managed attribute documentation) containing just the fields you normally need to load and use that where you might otherwise call defer(). This makes your code more explicit to the reader, is slightly faster and consumes a little less memory in the Python process.