Files
Django/gvsdsdk/management/commands/gvsdsdk_init.py

136 lines
4.8 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""gvsdsdk init — 子服务器快速初始化 SAAS 表
用法:
python manage.py gvsdsdk_init --db saas
python manage.py gvsdsdk_init --db saas --dry-run # 仅打印 SQL
python manage.py gvsdsdk_init --db default --modules auth,commission,payment
此命令会根据 gvsdsdk 中的模型定义,在指定数据库中创建对应的表。
适用于子服务器独立部署时快速建表。
"""
from django.core.management.base import BaseCommand, CommandError
from django.db import connections
from django.apps import apps
class Command(BaseCommand):
help = '初始化 gvsdsdk SAAS 表结构(子服务器建表工具)'
def add_arguments(self, parser):
parser.add_argument(
'--db', default='saas',
help='目标数据库别名(默认 saas',
)
parser.add_argument(
'--dry-run', action='store_true',
help='仅打印建表 SQL不执行',
)
parser.add_argument(
'--modules', default='all',
help='要初始化的模块逗号分隔all, auth, commission, payment。默认 all',
)
def handle(self, *args, **options):
db_alias = options['db']
dry_run = options['dry_run']
modules_str = options['modules']
# 验证数据库连接
try:
connection = connections[db_alias]
except KeyError:
raise CommandError(f'数据库别名 "{db_alias}" 未配置,请在 DATABASES 中添加')
# 收集 gvsdsdk 模型
target_modules = self._parse_modules(modules_str)
models_to_create = self._collect_models(target_modules)
if not models_to_create:
self.stdout.write(self.style.WARNING('没有找到需要创建的模型'))
return
self.stdout.write(f'找到 {len(models_to_create)} 个模型:')
for model in models_to_create:
self.stdout.write(f' - {model.__name__}{model._meta.db_table}')
# 生成建表 SQL
schema_editor = connection.schema_editor(collect_sql=True)
for model in models_to_create:
try:
schema_editor.create_model(model)
except Exception as e:
self.stdout.write(self.style.ERROR(f' 生成 {model.__name__} SQL 失败: {e}'))
sql_statements = schema_editor.collected_sql
if dry_run:
self.stdout.write(self.style.SUCCESS('\n=== DRY RUN: 建表 SQL ==='))
for sql in sql_statements:
self.stdout.write(sql)
self.stdout.write(self.style.SUCCESS(f'\n{len(sql_statements)} 条 SQL'))
return
# 执行建表
self.stdout.write(f'\n在数据库 "{db_alias}" 中创建表...')
try:
with connection.cursor() as cursor:
for sql in sql_statements:
cursor.execute(sql)
self.stdout.write(self.style.SUCCESS(f'成功创建 {len(sql_statements)} 个表'))
except Exception as e:
raise CommandError(f'建表失败: {e}')
def _parse_modules(self, modules_str):
if modules_str == 'all':
return {'auth', 'commission', 'payment'}
return set(m.strip() for m in modules_str.split(',') if m.strip())
def _collect_models(self, target_modules):
"""收集 gvsdsdk 中需要建表的模型"""
all_models = []
# 核心模型auth 相关User, Role, Permission, UserRole 等)
if 'auth' in target_modules:
try:
from gvsdsdk import models as core_models
for name in dir(core_models):
obj = getattr(core_models, name)
if self._is_qmodel(obj):
all_models.append(obj)
except Exception:
pass
# 分佣模型
if 'commission' in target_modules:
try:
from gvsdsdk.commission import models as comm_models
for name in dir(comm_models):
obj = getattr(comm_models, name)
if self._is_qmodel(obj):
all_models.append(obj)
except Exception:
pass
# 支付模型
if 'payment' in target_modules:
try:
from gvsdsdk.payment import models as pay_models
for name in dir(pay_models):
obj = getattr(pay_models, name)
if self._is_qmodel(obj):
all_models.append(obj)
except Exception:
pass
return all_models
def _is_qmodel(self, obj):
"""判断是否为 QModel 子类(非抽象)"""
from gvsdsdk.model_base import QModel
return (
isinstance(obj, type)
and issubclass(obj, QModel)
and not obj._meta.abstract
)