Django / REST-Framework / PostgreSQL project.
There are models connected mainly one-to-many, and an API that makes queries to the database.
Now there are about 700-1500 queries to the database when loading some pages, the database is growing and will be worse. Which way to look to solve problems?
Edit existing code / use raw queries? As I understand, this is a temporary solution and we will again rest on the ceiling.
Key-Value Stores - Redis / memcached and TP? But here, as I also assume, there is a ceiling with the growth of data and we must change the structure of the project.
In search of a solution, I saw another way - block reading from a database. Explain about it. Can we use it when building an API? For example, to give data gradually, up to one record and transfer it to the consumer? Can we combine the use of block reading and key-value storage?
What other comments are there on these methods and what do I disregard?
Added a piece of code to understand. There are two related models. The first one corresponds to 120 entries in the table, the second one is more than 10,000 (approximately 100 Property objects per Element)
class Element(models.Model): name = models.CharField(verbose_name="Name", max_length=255, blank=True, null=True) class Meta: verbose_name = "Element" verbose_name_plural = "Elements" class Property(models.Model): element = ForeignKey(Element, related_name='properties') title = models.CharField(max_length=255) type = models.CharField(max_length=50, choices=TYPE) value = models.CharField(max_length=255, blank=True, null=True) class Meta: verbose_name = "Property" verbose_name_plural = "Properties" ordering = ('title',) From the API, I get the following structure - I need to fetch from certain rows of the property table
[ { "name": "Lithium", "properties": { "group": "1", "atomic_number": "3", "symbol": "Li", "period": "2", "atomic_weight": "6.941", "type": "alkali" } }, { "name": "Beryllium", "properties": { "group": "2", "atomic_number": "4", "symbol": "Be", "period": "2", "atomic_weight": "9.012182", "type": "alkaline" } } ... In one of the methods I use queries of the form (obj is an object of the Element model)
def get_properties(self, obj): properties = ['Symbol', 'Group', 'Period', 'Type', 'Atomic weight', 'Atomic number'] func = lambda property: obj.properties.get(title=property).value if obj.properties.filter(title=property).exists() else None data = map(func, properties) return dict(zip(properties, data)) Here the check in this function doubles the number of requests to the database, we remove the check - the number of requests drops twice, I don’t understand how to get around
func = lambda property: obj.properties.get(title=property).value if obj.properties.filter(title=property).exists() else None