How to use Django database function expressions directly

Django has a many built-in database functions and a documented Func API for writing your own. Whilst writing a custom Func subclass may sometimes be necessary, I learnt that there’s many cases when you can instantiate Func with the necessary arguments to get what you need. For example, take the following model. from django.contrib.postgres.fields import ArrayField from django.db import models class Post(models.Model): tags = ArrayField(models.CharField(max_length=200)) Making use of the array_shuffle Postgres Array Function and an annotation, each of the post’s tags are in a randomised order. ...

October 2, 2024 · James Beith

How to enqueue Celery tasks using RabbitMQ message priorities

I have some slow running, low priority Celery tasks that I don’t want holding up more important tasks. I learnt how to configure Celery tasks, and queues, to support message priorities. Note, the project in question uses Django, Celery, and RabbitMQ. Firstly, I needed to decide on my priority values. Whilst RabbitMQ supports priorities between 1 and 255, their docs highly recommend using values between 1 and 5. It is important to know that higher priority values require more CPU and memory resources, since RabbitMQ needs to internally maintain a sub-queue for each priority from 1, up to the maximum value configured for a given queue. — https://www.rabbitmq.com/docs/priority ...

August 28, 2024 · James Beith

How to encode Unicode characters to store in AWS S3 object metadata

I recently ran into this error uploading images to AWS S3 using the boto3 package. Parameter validation failed: Non ascii characters found in S3 metadata for key “filename”, value: “ACME™ Anvil.jpg”. S3 metadata can only contain ASCII characters. The character in question was ™. Here’s a simplified example of the code. filename = "ACME™ Anvil.jpg" metadata: dict[str, str] = { "filename": filename, } client.upload_fileobj( Fileobj=..., Bucket=..., Key=..., ExtraArgs={"Metadata": metadata} ) I wanted to preserve the original filename, so I learnt to use backslashreplace when encoding the filename to ASCII. Note, I have to subsequently use .decode() as both metadata keys and values must be str, not bytes. ...

August 5, 2024 · James Beith

How to create a Django model index with an upper case empty string condition

Let’s say I have the following Django model. from django.db import models class User(models.Model): name = models.CharField(blank=True) And I want to filter those like so. users = User.objects.filter(name__istartswith="John") That would perform the following query. SELECT "data_user"."id", "data_user"."name" FROM "data_user" WHERE UPPER("data_user"."name"::text) LIKE UPPER('John%') I can improve the performance of that query by adding the following index to the model. To complement the use of UPPER() in the query I can use the Upper() function for the index’s expression. ...

May 2, 2024 · James Beith