Django的元数据库的最佳实践是什么?

时间:2022-11-28 08:59:07

I have to develop a webservice for storing data and I want to do it on Python/Django. It has only 2 elements at frontend - a table and a diagram. So basically the output in template is totally standard for all the views in all apps. I have 2 classes that compile data for output for these 2 elements in JSON, that goes to ReactJS at frontend.

我必须开发一个用于存储数据的web服务,我想在Python / Django上进行。它在前端只有2个元素 - 一个表和一个图表。所以基本上模板中的输出完全是所有应用程序中所有视图的标准。我有2个类,用于为JSON中的这2个元素的输出编译数据,前端到ReactJS。

Now, I have several apps and the only difference between them are models. Even CRUD-views and URLS are almost the same for all them. So i'm thinking of using some metadatabase to store all data in a unified way. Like storing all values in 3 tables - for strings, int and float.

现在,我有几个应用程序,它们之间的唯一区别是模型。甚至CRUD视图和URL也几乎相同。所以我想使用一些元数据库以统一的方式存储所有数据。就像将所有值存储在3个表中一样 - 用于字符串,int和float。

The thing that i'm afraid of is performance. If all my metadata like types of objects, categories and so on will be stored in a single table, I guess it will be hell to get even a simple value out of 4 or 5 requests using Django ORM and a common model for all things in the system.

我害怕的是表现。如果我的所有元数据(如对象类型,类别等)都将存储在一个表中,我想使用Django ORM以及所有事物的通用模型来获取4或5个请求中的简单值将是完美的。系统。

On the other hand, there's an option that I can't create new models programmatically on the fly. Once it's in production - there should be no changes in the code, because of the checksum of the project files.

另一方面,有一个选项,我不能动态地以编程方式创建新模型。一旦生产 - 由于项目文件的校验和,代码中不应该有任何变化。

I need an advice how to handle this situation. I thought of something like Drupal metadatabase, but Drupal creates new tables on the fly, and it doesn't need models in the code to work with them. Is there a way to do it like that in Django?

我需要一个如何处理这种情况的建议。我想到了像Drupal metadatabase这样的东西,但Drupal动态创建了新表,并且代码中不需要模型来使用它们。有没有办法像Django那样做?

1 个解决方案

#1


Judging from your requirements you would probably need to use Generic relations: https://docs.djangoproject.com/en/1.8/ref/contrib/contenttypes/ but it wont be the end of the world if all metadata are saved in a single table. Lets say you have a 3 different models strings, ints, floats. You need to create a MetaData Model that acts as a key value store:

从您的要求来看,您可能需要使用通用关系:https://docs.djangoproject.com/en/1.8/ref/contrib/contenttypes/但如果所有元数据都保存在一个单一的世界末日,它就不会是世界末日表。假设你有3种不同的模型字符串,整数,浮点数。您需要创建一个充当键值存储的MetaData模型:

class MetaData(models.Model):
    key = models.CharField(max_length=256, db_index=True)
    value = models.CharField(max_length=256)

    # Generic relationship to an arbitrary object
    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()
    content_object = generic.GenericForeignKey('content_type', 'object_id')

Then in a simple case you can use save values to this table like that: f=Float.objects.get(pk=1) v = MetaData(content_object=f, key="float_calculation_precision", value="6") v.save()

然后在一个简单的例子中,你可以像这样使用保存值:f = Float.objects.get(pk = 1)v = MetaData(content_object = f,key =“float_calculation_precision”,value =“6”)v。保存()

If you know before hand that you are going to be using only those 3 models you can add a reverse GenericRelation field on each one of those models.

如果您事先知道您将仅使用这3个模型,则可以在每个模型上添加反向GenericRelation字段。

class Floats(models.Model):
    metadata = generic.GenericRelation(MetaData)

class Ints(models.Model):
    metadata = generic.GenericRelation(MetaData)

class Strings(models.Model):
    metadata = generic.GenericRelation(MetaData)

and then you can access their metadata like that:

然后你可以像这样访问他们的元数据:

Floats.metadata.all()

to get all metadata objects or:

获取所有元数据对象或:

f = Floats.objects.get(pk=1)

f.metadata.all()

to get all metadata objects for a specific object:

获取特定对象的所有元数据对象:

You can also use https://github.com/rafaelsierra/django-metadata package where you can do something like that:

您还可以使用https://github.com/rafaelsierra/django-metadata包,您可以在其中执行以下操作:

mymodel.metadata['something'] = 'some value'
mymodel.metadata['something']

#1


Judging from your requirements you would probably need to use Generic relations: https://docs.djangoproject.com/en/1.8/ref/contrib/contenttypes/ but it wont be the end of the world if all metadata are saved in a single table. Lets say you have a 3 different models strings, ints, floats. You need to create a MetaData Model that acts as a key value store:

从您的要求来看,您可能需要使用通用关系:https://docs.djangoproject.com/en/1.8/ref/contrib/contenttypes/但如果所有元数据都保存在一个单一的世界末日,它就不会是世界末日表。假设你有3种不同的模型字符串,整数,浮点数。您需要创建一个充当键值存储的MetaData模型:

class MetaData(models.Model):
    key = models.CharField(max_length=256, db_index=True)
    value = models.CharField(max_length=256)

    # Generic relationship to an arbitrary object
    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()
    content_object = generic.GenericForeignKey('content_type', 'object_id')

Then in a simple case you can use save values to this table like that: f=Float.objects.get(pk=1) v = MetaData(content_object=f, key="float_calculation_precision", value="6") v.save()

然后在一个简单的例子中,你可以像这样使用保存值:f = Float.objects.get(pk = 1)v = MetaData(content_object = f,key =“float_calculation_precision”,value =“6”)v。保存()

If you know before hand that you are going to be using only those 3 models you can add a reverse GenericRelation field on each one of those models.

如果您事先知道您将仅使用这3个模型,则可以在每个模型上添加反向GenericRelation字段。

class Floats(models.Model):
    metadata = generic.GenericRelation(MetaData)

class Ints(models.Model):
    metadata = generic.GenericRelation(MetaData)

class Strings(models.Model):
    metadata = generic.GenericRelation(MetaData)

and then you can access their metadata like that:

然后你可以像这样访问他们的元数据:

Floats.metadata.all()

to get all metadata objects or:

获取所有元数据对象或:

f = Floats.objects.get(pk=1)

f.metadata.all()

to get all metadata objects for a specific object:

获取特定对象的所有元数据对象:

You can also use https://github.com/rafaelsierra/django-metadata package where you can do something like that:

您还可以使用https://github.com/rafaelsierra/django-metadata包,您可以在其中执行以下操作:

mymodel.metadata['something'] = 'some value'
mymodel.metadata['something']