Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django : shell plus --print-sql showing incomplete sql if the query is long

Tags:

django

I am using Django 2.0.

I have the the following models:

class SingleMeasurements (models.Model):
    MASS = 'kg'
    VOLUME = 'ltr'
    PIECES = 'pcs'
    MUNITS_CHOICES = (
        (VOLUME, 'Liter'),
        (MASS, 'Kilogram'),
        (PIECES, 'Pieces'),
        )

    name = models.CharField(max_length=200,unique=True,null=False)
    slug = models.SlugField(unique=True)
    formtype = models.CharField(max_length=10,choices=MUNITS_CHOICES,verbose_name="Units")
    quantity = models.DecimalField(max_digits=19, decimal_places=10)
    updated = models.DateTimeField(auto_now=True, auto_now_add=False)
    timestamp = models.DateTimeField(auto_now=False, auto_now_add=True)

class Recipe(models.Model):
    MASS = 'kg'
    VOLUME = 'ltr'
    PIECES = 'pcs'
    MUNITS_CHOICES = (
        (MASS, 'Mass'),
        (VOLUME, 'Volume'),
        (PIECES, 'Pieces'),
        )
    name = models.CharField(max_length=200)
    slug = models.SlugField(unique=True)
    tags = models.ManyToManyField(Tag,related_name='recipes_recipe_tag',blank=True)
    primary_unit = models.CharField(max_length=10,choices=MUNITS_CHOICES,default=VOLUME,verbose_name="Preferred Display Units",null=True,blank=True)
    mass_unit = models.ForeignKey(SingleMeasurements,on_delete=models.PROTECT,related_name='recipe_singlemeasurement_mass_unit',blank=True,null=True)
    mass_quantity = models.DecimalField(max_digits=19, decimal_places=10,null=True,blank=True)
    volume_unit = models.ForeignKey(SingleMeasurements,on_delete=models.PROTECT,related_name='recipe_singlemeasurement_volume_unit',blank=True,null=True)
    volume_quantity = models.DecimalField(max_digits=19, decimal_places=10,null=True,blank=True)
    pieces_unit = models.ForeignKey(SingleMeasurements,on_delete=models.PROTECT,related_name='recipe_singlemeasurement_pieces_unit',blank=True,null=True)
    pieces_quantity = models.DecimalField(max_digits=19, decimal_places=10,null=True,blank=True)
    updated = models.DateTimeField(auto_now=True, auto_now_add=False)
    timestamp = models.DateTimeField(auto_now=False, auto_now_add=True)

I have opened Django shell by the following command:

python manage.py shell_plus --print-sql --ipython

I am trying to run the following command

Recipe.objects.select_related('mass_unit','volume_unit','pieces_unit').all()

the output is:

In [19]: Recipe.objects.select_related('mass_unit','volume_unit','pieces_unit').all()
Out[19]: SELECT "recipes_recipe"."id",
       "recipes_recipe"."name",
       "recipes_recipe"."slug",
       "recipes_recipe"."primary_unit",
       "recipes_recipe"."mass_unit_id",
       "recipes_recipe"."mass_quantity",
       "recipes_recipe"."volume_unit_id",
       "recipes_recipe"."volume_quantity",
       "recipes_recipe"."pieces_unit_id",
       "recipes_recipe"."pieces_quantity",
       "recipes_recipe"."updated",
       "recipes_recipe"."timestamp",
       "single_measurements_singlemeasurements"."id",
       "single_measurements_singlemeasurements"."name",
       "single_measurements_singlemeasurements"."slug",
       "single_measurements_singlemeasurements"."formtype",
       "single_measurements_singlemeasurements"."quantity",
       "single_measurements_singlemeasurements"."updated",
       "single_measurements_singlemeasurements"."timestamp",
       T3."id",
       T3."name",
       T3."slug",
       T3."formtype",
       T3."quantity",
       T3."updated",
       T3."timestamp",
       T4."id",
       T4."name",
       T4."slug",
       T4."formtype",
       T4."quantity",
       T4."updated",
       T4."timestamp"
  FROM "recipes_recipe"
  LEFT OUTER JOIN "single_measurements_singlemeasurements"
    ON


Execution time: 0.001236s [Database: default]

And we can see the sql is incomplete, it has to show three left inner joins but it stops at ON.

Whereas if I try:

Recipe.objects.select_related('mass_unit').all()

It shows the full sql:

In [20]: Recipe.objects.select_related('mass_unit').all()
Out[20]: SELECT "recipes_recipe"."id",
       "recipes_recipe"."name",
       "recipes_recipe"."slug",
       "recipes_recipe"."primary_unit",
       "recipes_recipe"."mass_unit_id",
       "recipes_recipe"."mass_quantity",
       "recipes_recipe"."volume_unit_id",
       "recipes_recipe"."volume_quantity",
       "recipes_recipe"."pieces_unit_id",
       "recipes_recipe"."pieces_quantity",
       "recipes_recipe"."updated",
       "recipes_recipe"."timestamp",
       "single_measurements_singlemeasurements"."id",
       "single_measurements_singlemeasurements"."name",
       "single_measurements_singlemeasurements"."slug",
       "single_measurements_singlemeasurements"."formtype",
       "single_measurements_singlemeasurements"."quantity",
       "single_measurements_singlemeasurements"."updated",
       "single_measurements_singlemeasurements"."timestamp"
  FROM "recipes_recipe"
  LEFT OUTER JOIN "single_measurements_singlemeasurements"
    ON ("recipes_recipe"."mass_unit_id" = "single_measurements_singlemeasurements"."id")
 ORDER BY "recipes_recipe"."name" ASC
 LIMIT 21

Here it does not stop at ON. It shows the full.

How to ensure --print-sql shows the full sql.

like image 491
Santhosh Avatar asked Aug 25 '18 08:08

Santhosh


2 Answers

Add these to your settings.py:

for python manage.py shell_plus --print-sql:
SHELL_PLUS_PRINT_SQL_TRUNCATE = {truncate limit} (it defaults to 1000)

for python manage.py runserver_plus --print-sql:
RUNSERVER_PLUS_PRINT_SQL_TRUNCATE = {truncate limit} (it defaults to 1000)

Note the truncate limit is a number of characters, NOT lines, to truncate the sql output to.

like image 80
Prateek Madhikar Avatar answered Nov 11 '22 23:11

Prateek Madhikar


Including

SHELL_PLUS_PRINT_SQL_TRUNCATE = None

in your settings.py file will ensure --print-sql shows the full SQL query.

You can read more about the configurations here

like image 33
jo-0 Avatar answered Nov 11 '22 23:11

jo-0