【问题标题】:Add BrinIndex to existing PostgreSQL database using Django使用 Django 将 BrinIndex 添加到现有的 PostgreSQL 数据库
【发布时间】:2018-11-20 21:48:27
【问题描述】:

我正在使用 Django 运行一个网站,其中的数据库在 PostgreSQL 上运行。为了提高性能,我想将 BrinIndex 添加到磁盘上自然排序的模型中。

我已将索引添加到我的模型定义中,如下所示。

from django.contrib.postgres.indexes import BrinIndex

class Measurement(models.Model):
    class Meta:
        indexes = (
            BrinIndex(fields=['time'])
        )

    time = models.DateTimeField(
        'Time of measurement',
        null=True
    )

但正在运行

python3 manage.py makemigrations

返回错误

Traceback (most recent call last):
  File "C:\Program Files\JetBrains\PyCharm 2018.1.1\helpers\pycharm\django_manage.py", line 52, in <module>
    run_command()
  File "C:\Program Files\JetBrains\PyCharm 2018.1.1\helpers\pycharm\django_manage.py", line 46, in run_command
    run_module(manage_file, None, '__main__', True)
  File "C:\Python36\lib\runpy.py", line 205, in run_module
    return _run_module_code(code, init_globals, run_name, mod_spec)
  File "C:\Python36\lib\runpy.py", line 96, in _run_module_code
    mod_name, mod_spec, pkg_name, script_name)
  File "C:\Python36\lib\runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "C:/Users/*USERNAME*/*PROJECT_NAME*\manage.py", line 22, in <module>
    execute_from_command_line(sys.argv)
  File "C:\Users\*USERNAME*\*PROJECT_NAME*\venv\lib\site-packages\django\core\management\__init__.py", line 371, in execute_from_command_line
    utility.execute()
  File "C:\Users\*USERNAME*\*PROJECT_NAME*\venv\lib\site-packages\django\core\management\__init__.py", line 347, in execute
    django.setup()
  File "C:\Users\*USERNAME*\*PROJECT_NAME*\venv\lib\site-packages\django\__init__.py", line 24, in setup
    apps.populate(settings.INSTALLED_APPS)
  File "C:\Users\*USERNAME*\*PROJECT_NAME*\venv\lib\site-packages\django\apps\registry.py", line 112, in populate
    app_config.import_models()
  File "C:\Users\*USERNAME*\*PROJECT_NAME*\venv\lib\site-packages\django\apps\config.py", line 198, in import_models
    self.models_module = import_module(models_module_name)
  File "C:\Python36\lib\importlib\__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 978, in _gcd_import
  File "<frozen importlib._bootstrap>", line 961, in _find_and_load
  File "<frozen importlib._bootstrap>", line 950, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 655, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 678, in exec_module
  File "<frozen importlib._bootstrap>", line 205, in _call_with_frames_removed
  File "C:/Users/*USERNAME*/*PROJECT_NAME*\*APP_NAME*\models.py", line 300, in <module>
    class Measurement(models.Model):
  File "C:\Users\*USERNAME*\*PROJECT_NAME*\venv\lib\site-packages\django\db\models\base.py", line 298, in __new__
    new_class._meta.indexes = [copy.deepcopy(idx) for idx in new_class._meta.indexes]
TypeError: 'BrinIndex' object is not iterable

我做错了吗?以后可以不加这个索引吗?

【问题讨论】:

  • 你是否在你的models.py中导入django.contrib.postgres.indexes
  • 另外,您使用的是哪个版本的 Django? BrinIndex 仅在 1.11 及更高版本中受支持。
  • 我已经导入了 BrinIndex 并且正在运行 Django 2.0
  • 您是否检查了该字段是否为 NULL 影响索引能力(见我的回答)?

标签: python django postgresql indexing


【解决方案1】:

这是您的代码的问题 当定义具有单个值的元组时,您必须在值的末尾加上“,”,否则 python 不会将其识别为元组,例如:

a = ('value1') #is a string not a tuple
a = ('value1',) #is a tuple 

您的代码应如下所示: 从 django.contrib.postgres.indexes 导入 BrinIndex

class Measurement(models.Model):
    class Meta:
        indexes = (
            BrinIndex(fields=['time']),  # "," is added here
        )

    time = models.DateTimeField(
        'Time of measurement',
        null=True
    )

【讨论】:

    【解决方案2】:

    有几件事可以尝试:

    1. 您不能总是NULL 字段上有索引。我不知道BrinIndex 的内部工作原理,但您可能想检查一下。

    2. 您的模型定义应包含db_index 属性:

    from django.contrib.postgres.indexes import BrinIndex
    
    class Measurement(models.Model):
    
        time = models.DateTimeField(
            'Time of measurement',
            db_index=True,
            null=True
        )
    
        class Meta:
            indexes = (
                BrinIndex(fields=['time'])
            )
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-02-21
      • 1970-01-01
      • 2022-01-12
      • 2011-07-06
      • 2013-03-10
      • 2016-03-09
      • 1970-01-01
      • 2011-10-07
      相关资源
      最近更新 更多