django 建立安全索引

  上篇记录使用“CONCURRENTLY” 命令行执行不锁表索引,对于django, 如何执行呢?这里记录一种方法,修改django迁移文件。

  在执行完迁移后,为了方便找到该迁移文件,可以采用指定命名迁移

  python manage.py makemigrations --name=add_index_separate_database_and_state app01

  对应app/migrations文件夹自动生成mitration文件,例如:

 1 # migrations/0002_add_index_separate_database_and_state.py
 2 
 3 from django.db import migrations, models
 4 
 5 class Migration(migrations.Migration):
 6 
 7     dependencies = [
 8         ('app', '0001_initial'),
 9     ]
10 
11     operations = [
12         migrations.AlterField(
13             model_name='sale',
14             name='sold_at',
15             field=models.DateTimeField(
16                 auto_now_add=True,
17                 db_index=True,
18             ),
19         ),
20     ]

 

  在终端输出migratons文件sql语句,此处是为确保执行sql操作与django状态一致

 

1 $ python manage.py sqlmigrate app 0002
2 BEGIN;
3 --
4 -- Alter field sold_at on sale
5 --
6 CREATE INDEX "app_sale_sold_at_b9438ae4" ON "app_sale" ("sold_at");
7 COMMIT;

 

 接下来,需要使用“SeparateDatabaseAndState”来进行关联,我们知道,Django模型和数据库属于映射关系,django保存模型状态,和数据库之间同步需要明确指出。

 1 # migrations/0002_add_index_separate_database_and_state.py
 2 
 3 from django.db import migrations, models
 4 
 5 class Migration(migrations.Migration):
 6     atomic = False
 7 
 8     dependencies = [
 9         ('app', '0001_initial'),
10     ]
11 
12     operations = [
13 
14         migrations.SeparateDatabaseAndState(
15 
16             state_operations=[
17                 migrations.AlterField(
18                     model_name='sale',
19                     name='sold_at',
20                     field=models.DateTimeField(
21                         auto_now_add=True,
22                         db_index=True,
23                     ),
24                 ),
25             ],
26 
27             database_operations=[
28                 migrations.RunSQL(sql="""
29                     CREATE INDEX CONCURRENTLY "app_sale_sold_at_b9438ae4"
30                     ON "app_sale" ("sold_at");
31                 """,
32                 reverse_sql="""
33                     DROP INDEX "app_sale_sold_at_b9438ae4";
34                 """),
35             ],
36         ),
37 
38     ],
 state_operations: django此次修改动作,django自动生成动作,

state_operations:数据库执行操作,

reverse_sql: 类似与sql回滚,比如,迁移文件想回到上一版本时,需要将本迁移文件执行操作还原,但django不知道原始sql执行何种操作,所以,如果要回退,需要指定回滚sql。
另外,django迁移采用事务操作,而"CONCURRENTLY"不支持事务操作,可以采用非事务操作(不可回滚),如第6行所示。



文章参考:https://realpython.com/create-django-index-without-downtime/#execute-raw-sql-in-migrations



 

 

posted on 2019-07-15 10:45  努力记录点滴生活  阅读(881)  评论(0编辑  收藏  举报