背景
项目用的pg数据库,但是生成数据库时没有字段备注;查了很多资料没有合适的解决方案,还是自己来实现吧;
思路
可以做一个manage.py 命令,然后扫描所有的model获得元数据,然后组装sql直接操作数据库
扩展 manage.py 命令
扩展manage.py命令的具体做法参考这里
命令具体逻辑
我新建了一个util app然后将代码放在里面,代码已提交到Gitee
import sys
from django.apps import apps
from django.core.management.base import (
BaseCommand, CommandError, no_translations,
)
from django.db import connection
from django.conf import settings
class Command(BaseCommand):
def add_arguments(self, parser):
parser.add_argument(
'args', metavar='app_label', nargs='*',
help='Specify the app label(s) to create migrations for.',
)
parser.add_argument(
'--dry-run', action='store_true',
help="Just show what migrations would be made; don't actually write them.",
)
parser.add_argument(
'--merge', action='store_true',
help="Enable fixing of migration conflicts.",
)
parser.add_argument(
'--empty', action='store_true',
help="Create an empty migration.",
)
parser.add_argument(
'--noinput', '--no-input', action='store_false', dest='interactive',
help='Tells Django to NOT prompt the user for input of any kind.',
)
parser.add_argument(
'-n', '--name',
help="Use this name for migration file(s).",
)
parser.add_argument(
'--no-header', action='store_false', dest='include_header',
help='Do not add header comments to new migration file(s).',
)
parser.add_argument(
'--check', action='store_true', dest='check_changes',
help='Exit with a non-zero status if model changes are missing migrations.',
)
@no_translations
def handle(self, *app_labels, **options):
# Make sure the app they asked for exists
app_labels = set(app_labels)
has_bad_labels = False
for app_label in app_labels:
try:
apps.get_app_config(app_label)
except LookupError as err:
self.stderr.write(str(err))
has_bad_labels = True
if has_bad_labels:
sys.exit(2)
if len(app_labels) == 0:
print("请使用如下命令执行: python manage.py comments <app_label <app_label ...>>")
engine = settings.DATABASES['default']['ENGINE']
# 获得sql执行器
cursor = connection.cursor()
# 根据输入的app 做model字段备注修改
for app_name in app_labels:
app_conf = apps.get_app_config(app_name)
for model_name in app_conf.models:
model_meta = apps.get_model(app_name, model_name)._meta
# 获得table_name
table_name = model_meta.db_table
# 获得model里所以的字段
fields = model_meta.fields
for field in fields:
column_name = field.column
verbose_name = field.verbose_name
# 组装sql
# comment on column 表名.字段名 is '字段备注'
if self.is_pg_sql(engine):
sql = "comment on column %s.%s is '%s'" % (table_name, column_name, verbose_name)
else:
print("暂不支持:", engine)
cursor.execute(sql)
print('app:', app_name, '备注修改完毕')
def is_pg_sql(self, engine):
"""
是pg 数据库
:param engine:
:return:
"""
return 'django.db.backends.postgresql' == engine
def is_mysql(self, engine):
"""
判断是不是mysql
:param engine:
:return:
"""
return 'django.db.backends.mysql' == engine
测试
model
执行命令
我设计的是这个命令后面要带上若干个 app 名称,避免误操作
python manage.py comments xxx
数据库效果
代码已提交到Gitee
done