Skip to content

Commit 2b28244

Browse files
authored
Fix the plugin model object detection logic (#782)
1 parent f71071f commit 2b28244

File tree

4 files changed

+39
-34
lines changed

4 files changed

+39
-34
lines changed

backend/alembic/env.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,13 @@
33
# ruff: noqa: F403, F401, I001, RUF100
44
import asyncio
55
import os
6-
import sys
76
from logging.config import fileConfig
87

98
from alembic import context
109
from sqlalchemy import pool
1110
from sqlalchemy.engine import Connection
1211
from sqlalchemy.ext.asyncio import async_engine_from_config
1312

14-
sys.path.append('../')
15-
1613
from backend.app import get_app_models
1714
from backend.common.model import MappedBase
1815
from backend.core import path_conf

backend/app/__init__.py

Lines changed: 9 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
11
#!/usr/bin/env python3
22
# -*- coding: utf-8 -*-
3-
import inspect
43
import os.path
54

6-
from backend.common.log import log
75
from backend.core.path_conf import BASE_PATH
8-
from backend.utils.import_parse import import_module_cached
6+
from backend.utils.import_parse import get_model_object
97

108

11-
def get_app_models():
9+
def get_app_models() -> list[type]:
1210
"""获取 app 所有模型类"""
1311
app_path = os.path.join(BASE_PATH, 'app')
1412
list_dirs = os.listdir(app_path)
@@ -19,23 +17,15 @@ def get_app_models():
1917
if os.path.isdir(os.path.join(app_path, d)) and d != '__pycache__':
2018
apps.append(d)
2119

22-
classes = []
20+
objs = []
2321

2422
for app in apps:
25-
try:
26-
module_path = f'backend.app.{app}.model'
27-
module = import_module_cached(module_path)
28-
except ModuleNotFoundError as e:
29-
log.warning(f'应用 {app} 中不包含 model 相关配置: {e}')
30-
continue
31-
except Exception as e:
32-
raise e
33-
34-
for name, obj in inspect.getmembers(module):
35-
if inspect.isclass(obj):
36-
classes.append(obj)
37-
38-
return classes
23+
module_path = f'backend.app.{app}.model'
24+
obj = get_model_object(module_path)
25+
if obj:
26+
objs.append(obj)
27+
28+
return objs
3929

4030

4131
# import all app models for auto create db tables

backend/plugin/tools.py

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
#!/usr/bin/env python3
22
# -*- coding: utf-8 -*-
3-
import inspect
43
import json
54
import os
65
import subprocess
@@ -24,7 +23,7 @@
2423
from backend.core.path_conf import PLUGIN_DIR
2524
from backend.database.redis import RedisCli, redis_client
2625
from backend.utils._await import run_await
27-
from backend.utils.import_parse import import_module_cached
26+
from backend.utils.import_parse import get_model_object, import_module_cached
2827

2928

3029
class PluginConfigError(Exception):
@@ -60,19 +59,15 @@ def get_plugins() -> list[str]:
6059

6160
def get_plugin_models() -> list[type]:
6261
"""获取插件所有模型类"""
63-
classes = []
62+
objs = []
6463

6564
for plugin in get_plugins():
66-
# 导入插件的模型模块
6765
module_path = f'backend.plugin.{plugin}.model'
68-
module = import_module_cached(module_path)
69-
70-
# 获取模块中的所有类
71-
for name, obj in inspect.getmembers(module):
72-
if inspect.isclass(obj):
73-
classes.append(obj)
66+
obj = get_model_object(module_path)
67+
if obj:
68+
objs.append(obj)
7469

75-
return classes
70+
return objs
7671

7772

7873
async def get_plugin_sql(plugin: str, db_type: DataBaseType, pk_type: PrimaryKeyType) -> str | None:

backend/utils/import_parse.py

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#!/usr/bin/env python3
22
# -*- coding: utf-8 -*-
33
import importlib
4+
import inspect
45

56
from functools import lru_cache
67
from typing import Any, Type, TypeVar
@@ -33,6 +34,28 @@ def dynamic_import_data_model(module_path: str) -> Type[T]:
3334
module_path, class_name = module_path.rsplit('.', 1)
3435
module = import_module_cached(module_path)
3536
return getattr(module, class_name)
36-
except (ImportError, AttributeError) as e:
37+
except Exception as e:
3738
log.error(f'动态导入数据模型失败:{e}')
3839
raise errors.ServerError(msg='数据模型列动态解析失败,请联系系统超级管理员')
40+
41+
42+
def get_model_object(module_path: str) -> type | None:
43+
"""
44+
获取模型对象
45+
46+
:param module_path: 模块路径
47+
:return:
48+
"""
49+
try:
50+
module = import_module_cached(module_path)
51+
except ModuleNotFoundError:
52+
log.warning(f'模块 {module_path} 中不包含模型对象')
53+
return None
54+
except Exception as e:
55+
raise RuntimeError(f'获取模块 {module_path} 模型对象失败:{e}')
56+
57+
for name, obj in inspect.getmembers(module):
58+
if inspect.isclass(obj):
59+
return obj
60+
61+
return None

0 commit comments

Comments
 (0)