mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-09-05 07:27:15 +08:00
refactor: 推进后端分层架构治理
This commit is contained in:
+59
-27
@@ -1,28 +1,60 @@
|
||||
"""
|
||||
ORM 模型。
|
||||
"""ORM 模型的惰性兼容导出与显式注册入口。"""
|
||||
|
||||
_identity 必须在此处导入:它在 import 期把媒体身份归一挂到 mapper 事件上,是六张带
|
||||
身份列的表的写入不变量。导入任一模型都会先初始化本包,因此这一行让强制点无处可绕。
|
||||
"""
|
||||
from . import _identity # noqa: F401 仅为注册 mapper 事件,不导出符号
|
||||
from .agentchat import AgentChat
|
||||
from .agenttask import AgentTask
|
||||
from .agenttaskrun import AgentTaskRun
|
||||
from .downloadfailure import DownloadFailure
|
||||
from .downloadhistory import DownloadHistory, DownloadFiles
|
||||
from .mediaserver import MediaServerItem
|
||||
from .message import Message
|
||||
from .passkey import PassKey
|
||||
from .plugindata import PluginData
|
||||
from .site import Site
|
||||
from .siteicon import SiteIcon
|
||||
from .sitestatistic import SiteStatistic
|
||||
from .siteuserdata import SiteUserData
|
||||
from .subscribe import Subscribe
|
||||
from .subscribehistory import SubscribeHistory
|
||||
from .systemconfig import SystemConfig
|
||||
from .transferhistory import TransferHistory
|
||||
from .transferpending import TransferPending
|
||||
from .user import User
|
||||
from .userconfig import UserConfig
|
||||
from .workflow import Workflow
|
||||
from importlib import import_module
|
||||
from typing import Any
|
||||
|
||||
from . import _identity # noqa: F401 注册全局媒体身份写入不变量
|
||||
|
||||
|
||||
_MODEL_EXPORTS = {
|
||||
"AgentChat": ("app.db.models.agentchat", "AgentChat"),
|
||||
"AgentTask": ("app.db.models.agenttask", "AgentTask"),
|
||||
"AgentTaskRun": ("app.db.models.agenttaskrun", "AgentTaskRun"),
|
||||
"DownloadFailure": ("app.db.models.downloadfailure", "DownloadFailure"),
|
||||
"DownloadFiles": ("app.db.models.downloadhistory", "DownloadFiles"),
|
||||
"DownloadHistory": ("app.db.models.downloadhistory", "DownloadHistory"),
|
||||
"MediaServerItem": ("app.db.models.mediaserver", "MediaServerItem"),
|
||||
"Message": ("app.db.models.message", "Message"),
|
||||
"PassKey": ("app.db.models.passkey", "PassKey"),
|
||||
"PluginData": ("app.db.models.plugindata", "PluginData"),
|
||||
"Site": ("app.db.models.site", "Site"),
|
||||
"SiteIcon": ("app.db.models.siteicon", "SiteIcon"),
|
||||
"SiteStatistic": ("app.db.models.sitestatistic", "SiteStatistic"),
|
||||
"SiteUserData": ("app.db.models.siteuserdata", "SiteUserData"),
|
||||
"Subscribe": ("app.db.models.subscribe", "Subscribe"),
|
||||
"SubscribeHistory": (
|
||||
"app.db.models.subscribehistory",
|
||||
"SubscribeHistory",
|
||||
),
|
||||
"SystemConfig": ("app.db.models.systemconfig", "SystemConfig"),
|
||||
"TransferHistory": ("app.db.models.transferhistory", "TransferHistory"),
|
||||
"TransferPending": ("app.db.models.transferpending", "TransferPending"),
|
||||
"User": ("app.db.models.user", "User"),
|
||||
"UserConfig": ("app.db.models.userconfig", "UserConfig"),
|
||||
"Workflow": ("app.db.models.workflow", "Workflow"),
|
||||
}
|
||||
|
||||
|
||||
def load_all_models() -> None:
|
||||
"""显式导入全部 ORM 模型,供建表和 Alembic 元数据收集使用。"""
|
||||
for module_name, _ in dict.fromkeys(_MODEL_EXPORTS.values()):
|
||||
import_module(module_name)
|
||||
|
||||
|
||||
def __getattr__(name: str) -> Any:
|
||||
"""按需解析旧模型包级导出,并缓存模型类。"""
|
||||
contract = _MODEL_EXPORTS.get(name)
|
||||
if contract is None:
|
||||
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
|
||||
module_name, symbol_name = contract
|
||||
value = getattr(import_module(module_name), symbol_name)
|
||||
globals()[name] = value
|
||||
return value
|
||||
|
||||
|
||||
def __dir__() -> list[str]:
|
||||
"""返回模型包的兼容公开面。"""
|
||||
return sorted({*globals(), *_MODEL_EXPORTS, "load_all_models"})
|
||||
|
||||
|
||||
__all__ = [*_MODEL_EXPORTS, "load_all_models"]
|
||||
|
||||
@@ -4,7 +4,8 @@ from sqlalchemy import Integer, String, JSON, Index, select
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy.orm import Mapped, Session, mapped_column
|
||||
|
||||
from app.db import Base, async_db_query, db_query, get_id_column
|
||||
from app.db.base import Base, get_id_column
|
||||
from app.db.decorators import async_db_query, db_query
|
||||
|
||||
|
||||
class AgentChat(Base):
|
||||
|
||||
@@ -3,7 +3,8 @@ from typing import Optional
|
||||
from sqlalchemy import Boolean, Index, Integer, String, Text, select, update
|
||||
from sqlalchemy.orm import Mapped, Session, mapped_column
|
||||
|
||||
from app.db import Base, db_query, db_update, execute_dml, get_id_column
|
||||
from app.db.base import Base, execute_dml, get_id_column
|
||||
from app.db.decorators import db_query, db_update
|
||||
|
||||
|
||||
class AgentTask(Base):
|
||||
|
||||
@@ -3,7 +3,8 @@ from typing import Any, Dict, List, Optional
|
||||
from sqlalchemy import Index, Integer, String, Text, delete, select, update
|
||||
from sqlalchemy.orm import Mapped, Session, mapped_column
|
||||
|
||||
from app.db import Base, db_query, db_update, execute_dml, get_id_column
|
||||
from app.db.base import Base, execute_dml, get_id_column
|
||||
from app.db.decorators import db_query, db_update
|
||||
from app.db.models.agenttask import AgentTask
|
||||
|
||||
|
||||
|
||||
@@ -3,7 +3,8 @@ from typing import List, Optional
|
||||
from sqlalchemy import Float, Index, Integer, String, delete, select
|
||||
from sqlalchemy.orm import Mapped, Session, mapped_column
|
||||
|
||||
from app.db import Base, db_query, db_update, execute_dml, get_id_column
|
||||
from app.db.base import Base, execute_dml, get_id_column
|
||||
from app.db.decorators import db_query, db_update
|
||||
from app.db.models._constraints import media_identity_constraint
|
||||
|
||||
|
||||
|
||||
@@ -5,7 +5,8 @@ from sqlalchemy import Integer, String, JSON, Index, delete, select, func, updat
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy.orm import Mapped, Session, mapped_column
|
||||
|
||||
from app.db import Base, async_db_query, db_query, db_update, execute_dml, get_id_column
|
||||
from app.db.base import Base, execute_dml, get_id_column
|
||||
from app.db.decorators import async_db_query, db_query, db_update
|
||||
from app.db.models._constraints import media_identity_constraint
|
||||
from app.schemas.types import MediaSource
|
||||
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
from datetime import datetime
|
||||
from typing import Any, List, Optional
|
||||
|
||||
from sqlalchemy import Integer, String, JSON, Index, delete, or_
|
||||
from sqlalchemy import String, JSON, Index, delete, or_
|
||||
from sqlalchemy import select
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy.orm import Mapped, Session, mapped_column
|
||||
|
||||
from app.db import Base, async_db_query, db_query, db_update, execute_dml, get_id_column
|
||||
from app.db.base import Base, execute_dml, get_id_column
|
||||
from app.db.decorators import async_db_query, db_query, db_update
|
||||
from app.db.models._constraints import media_identity_constraint
|
||||
from app.schemas.types import MediaSource
|
||||
|
||||
|
||||
@@ -4,7 +4,8 @@ from sqlalchemy import Integer, String, JSON, Index, and_, delete, or_, select
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy.orm import Mapped, Session, mapped_column
|
||||
|
||||
from app.db import Base, async_db_query, db_query, db_update, execute_dml, get_id_column
|
||||
from app.db.base import Base, execute_dml, get_id_column
|
||||
from app.db.decorators import async_db_query, db_query, db_update
|
||||
|
||||
|
||||
class Message(Base):
|
||||
|
||||
@@ -4,7 +4,8 @@ from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy.orm import Mapped, Session, mapped_column
|
||||
from datetime import datetime
|
||||
|
||||
from app.db import Base, db_query, db_update, async_db_query, async_db_update, get_id_column
|
||||
from app.db.base import Base, get_id_column
|
||||
from app.db.decorators import db_query, db_update, async_db_query, async_db_update
|
||||
|
||||
|
||||
class PassKey(Base):
|
||||
|
||||
@@ -3,13 +3,8 @@ from sqlalchemy import String, JSON, Index, delete, select
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy.orm import Mapped, Session, mapped_column
|
||||
|
||||
from app.db import (
|
||||
db_query,
|
||||
db_update,
|
||||
async_db_query,
|
||||
get_id_column,
|
||||
Base,
|
||||
)
|
||||
from app.db.base import get_id_column, Base
|
||||
from app.db.decorators import db_query, db_update, async_db_query
|
||||
|
||||
|
||||
class PluginData(Base):
|
||||
|
||||
@@ -5,7 +5,8 @@ from sqlalchemy import Boolean, Integer, String, JSON, select, delete
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy.orm import Mapped, Session, mapped_column
|
||||
|
||||
from app.db import db_query, db_update, Base, async_db_query, async_db_update, get_id_column
|
||||
from app.db.base import Base, get_id_column
|
||||
from app.db.decorators import db_query, db_update, async_db_query, async_db_update
|
||||
|
||||
|
||||
class Site(Base):
|
||||
|
||||
@@ -3,7 +3,8 @@ from sqlalchemy import String, select
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy.orm import Mapped, Session, mapped_column
|
||||
|
||||
from app.db import db_query, Base, get_id_column, async_db_query
|
||||
from app.db.base import Base, get_id_column
|
||||
from app.db.decorators import db_query, async_db_query
|
||||
|
||||
|
||||
class SiteIcon(Base):
|
||||
|
||||
@@ -5,7 +5,8 @@ from sqlalchemy import Integer, String, JSON, delete, select
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy.orm import Mapped, Session, mapped_column
|
||||
|
||||
from app.db import db_query, db_update, get_id_column, Base, async_db_query
|
||||
from app.db.base import get_id_column, Base
|
||||
from app.db.decorators import db_query, db_update, async_db_query
|
||||
|
||||
|
||||
class SiteStatistic(Base):
|
||||
|
||||
@@ -5,7 +5,8 @@ from sqlalchemy import Integer, String, Float, JSON, Index, delete, func, or_, s
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy.orm import Mapped, Session, mapped_column
|
||||
|
||||
from app.db import Base, async_db_query, db_query, db_update, execute_dml, get_id_column
|
||||
from app.db.base import Base, execute_dml, get_id_column
|
||||
from app.db.decorators import async_db_query, db_query, db_update
|
||||
|
||||
|
||||
class SiteUserData(Base):
|
||||
|
||||
@@ -5,7 +5,8 @@ from sqlalchemy import Integer, String, Float, JSON, Index, delete, or_, select
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy.orm import Mapped, Session, mapped_column
|
||||
|
||||
from app.db import db_query, db_update, get_id_column, Base, async_db_query, async_db_update
|
||||
from app.db.base import get_id_column, Base
|
||||
from app.db.decorators import db_query, db_update, async_db_query, async_db_update
|
||||
from app.db.models._constraints import media_identity_constraint
|
||||
from app.schemas.types import MUSIC_ENTITY_RECORDING, MediaSource
|
||||
|
||||
|
||||
@@ -4,7 +4,8 @@ from sqlalchemy import Integer, String, Float, JSON, Index, or_, select
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy.orm import Mapped, Session, mapped_column
|
||||
|
||||
from app.db import db_query, Base, get_id_column, async_db_query
|
||||
from app.db.base import Base, get_id_column
|
||||
from app.db.decorators import db_query, async_db_query
|
||||
from app.db.models._constraints import media_identity_constraint
|
||||
from app.schemas.types import MUSIC_ENTITY_RECORDING, MediaSource
|
||||
|
||||
|
||||
@@ -3,7 +3,8 @@ from sqlalchemy import String, JSON, select
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy.orm import Mapped, Session, mapped_column
|
||||
|
||||
from app.db import db_query, db_update, Base, async_db_query, get_id_column
|
||||
from app.db.base import Base, get_id_column
|
||||
from app.db.decorators import db_query, db_update, async_db_query
|
||||
|
||||
|
||||
class SystemConfig(Base):
|
||||
|
||||
@@ -7,7 +7,8 @@ from sqlalchemy import Boolean, Index, Integer, JSON, String, delete, func, or_,
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy.orm import Mapped, Session, mapped_column
|
||||
|
||||
from app.db import Base, async_db_query, db_query, db_update, execute_dml, get_id_column
|
||||
from app.db.base import Base, execute_dml, get_id_column
|
||||
from app.db.decorators import async_db_query, db_query, db_update
|
||||
from app.db.models._constraints import media_identity_constraint
|
||||
from app.schemas.types import MUSIC_ENTITY_ALBUM, MUSIC_ENTITY_RECORDING, MediaSource, MediaType
|
||||
|
||||
|
||||
@@ -3,7 +3,8 @@ from typing import List, Optional
|
||||
from sqlalchemy import Index, String, delete, select
|
||||
from sqlalchemy.orm import Mapped, Session, mapped_column
|
||||
|
||||
from app.db import Base, db_query, db_update, execute_dml, get_id_column
|
||||
from app.db.base import Base, execute_dml, get_id_column
|
||||
from app.db.decorators import db_query, db_update
|
||||
|
||||
|
||||
class TransferPending(Base):
|
||||
|
||||
@@ -3,7 +3,8 @@ from sqlalchemy import Boolean, JSON, String, select
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy.orm import Mapped, Session, mapped_column
|
||||
|
||||
from app.db import Base, db_query, db_update, async_db_query, async_db_update, get_id_column
|
||||
from app.db.base import Base, get_id_column
|
||||
from app.db.decorators import db_query, db_update, async_db_query, async_db_update
|
||||
|
||||
|
||||
class User(Base):
|
||||
|
||||
@@ -2,7 +2,8 @@ from typing import Any, Optional
|
||||
from sqlalchemy import String, UniqueConstraint, JSON, select
|
||||
from sqlalchemy.orm import Mapped, Session, mapped_column
|
||||
|
||||
from app.db import db_query, db_update, get_id_column, Base
|
||||
from app.db.base import get_id_column, Base
|
||||
from app.db.decorators import db_query, db_update
|
||||
|
||||
|
||||
class UserConfig(Base):
|
||||
|
||||
@@ -6,7 +6,8 @@ from sqlalchemy import Integer, JSON, String, Index, and_, or_, select, update
|
||||
from sqlalchemy.orm import Mapped, mapped_column
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from app.db import Base, db_query, get_id_column, db_update, async_db_query, async_db_update
|
||||
from app.db.base import Base, get_id_column
|
||||
from app.db.decorators import db_query, db_update, async_db_query, async_db_update
|
||||
|
||||
|
||||
class Workflow(Base):
|
||||
|
||||
Reference in New Issue
Block a user