- 偿试修复可执行文件打包插件数据表缺失问题
This commit is contained in:
parent
1323cd5dc6
commit
f0fbad889d
@ -1,7 +1,10 @@
|
||||
from typing import Any, Self, List
|
||||
from typing import Tuple, Optional, Generator
|
||||
|
||||
from sqlalchemy import create_engine, QueuePool
|
||||
from sqlalchemy.orm import sessionmaker, Session, scoped_session
|
||||
from sqlalchemy import inspect
|
||||
from sqlalchemy.orm import declared_attr
|
||||
from sqlalchemy.orm import sessionmaker, Session, scoped_session, as_declarative
|
||||
|
||||
from app.core.config import settings
|
||||
|
||||
@ -135,6 +138,52 @@ def db_query(func):
|
||||
return wrapper
|
||||
|
||||
|
||||
@as_declarative()
|
||||
class Base:
|
||||
id: Any
|
||||
__name__: str
|
||||
|
||||
@db_update
|
||||
def create(self, db: Session):
|
||||
db.add(self)
|
||||
|
||||
@classmethod
|
||||
@db_query
|
||||
def get(cls, db: Session, rid: int) -> Self:
|
||||
return db.query(cls).filter(cls.id == rid).first()
|
||||
|
||||
@db_update
|
||||
def update(self, db: Session, payload: dict):
|
||||
payload = {k: v for k, v in payload.items() if v is not None}
|
||||
for key, value in payload.items():
|
||||
setattr(self, key, value)
|
||||
if inspect(self).detached:
|
||||
db.add(self)
|
||||
|
||||
@classmethod
|
||||
@db_update
|
||||
def delete(cls, db: Session, rid):
|
||||
db.query(cls).filter(cls.id == rid).delete()
|
||||
|
||||
@classmethod
|
||||
@db_update
|
||||
def truncate(cls, db: Session):
|
||||
db.query(cls).delete()
|
||||
|
||||
@classmethod
|
||||
@db_query
|
||||
def list(cls, db: Session) -> List[Self]:
|
||||
result = db.query(cls).all()
|
||||
return list(result)
|
||||
|
||||
def to_dict(self):
|
||||
return {c.name: getattr(self, c.name, None) for c in self.__table__.columns}
|
||||
|
||||
@declared_attr
|
||||
def __tablename__(self) -> str:
|
||||
return self.__name__.lower()
|
||||
|
||||
|
||||
class DbOper:
|
||||
"""
|
||||
数据库操作基类
|
||||
|
@ -1,15 +1,10 @@
|
||||
import importlib
|
||||
from pathlib import Path
|
||||
|
||||
from alembic.command import upgrade
|
||||
from alembic.config import Config
|
||||
|
||||
from app.core.config import settings
|
||||
from app.core.security import get_password_hash
|
||||
from app.db import Engine, SessionFactory
|
||||
from app.db.models import Base
|
||||
from app.db.models.user import User
|
||||
from app.helper.module import ModuleHelper
|
||||
from app.db import Engine, SessionFactory, Base
|
||||
from app.db.models import *
|
||||
from app.log import logger
|
||||
|
||||
|
||||
@ -17,21 +12,18 @@ def init_db():
|
||||
"""
|
||||
初始化数据库
|
||||
"""
|
||||
# 导入模块,避免建表缺失
|
||||
models_path = Path(__file__).with_name("models")
|
||||
ModuleHelper.dynamic_import_all_modules(models_path, "app.db.models")
|
||||
# 全量建表
|
||||
Base.metadata.create_all(bind=Engine)
|
||||
# 初始化超级管理员
|
||||
with SessionFactory() as db:
|
||||
user = User.get_by_name(db=db, name=settings.SUPERUSER)
|
||||
if not user:
|
||||
user = User(
|
||||
_user = User.get_by_name(db=db, name=settings.SUPERUSER)
|
||||
if not _user:
|
||||
_user = User(
|
||||
name=settings.SUPERUSER,
|
||||
hashed_password=get_password_hash(settings.SUPERUSER_PASSWORD),
|
||||
is_superuser=True,
|
||||
)
|
||||
user.create(db)
|
||||
_user.create(db)
|
||||
|
||||
|
||||
def update_db():
|
||||
|
@ -1,52 +1,9 @@
|
||||
from typing import Any, Self, List
|
||||
|
||||
from sqlalchemy import inspect
|
||||
from sqlalchemy.orm import as_declarative, declared_attr, Session
|
||||
|
||||
from app.db import db_update, db_query
|
||||
|
||||
|
||||
@as_declarative()
|
||||
class Base:
|
||||
id: Any
|
||||
__name__: str
|
||||
|
||||
@db_update
|
||||
def create(self, db: Session):
|
||||
db.add(self)
|
||||
|
||||
@classmethod
|
||||
@db_query
|
||||
def get(cls, db: Session, rid: int) -> Self:
|
||||
return db.query(cls).filter(cls.id == rid).first()
|
||||
|
||||
@db_update
|
||||
def update(self, db: Session, payload: dict):
|
||||
payload = {k: v for k, v in payload.items() if v is not None}
|
||||
for key, value in payload.items():
|
||||
setattr(self, key, value)
|
||||
if inspect(self).detached:
|
||||
db.add(self)
|
||||
|
||||
@classmethod
|
||||
@db_update
|
||||
def delete(cls, db: Session, rid):
|
||||
db.query(cls).filter(cls.id == rid).delete()
|
||||
|
||||
@classmethod
|
||||
@db_update
|
||||
def truncate(cls, db: Session):
|
||||
db.query(cls).delete()
|
||||
|
||||
@classmethod
|
||||
@db_query
|
||||
def list(cls, db: Session) -> List[Self]:
|
||||
result = db.query(cls).all()
|
||||
return list(result)
|
||||
|
||||
def to_dict(self):
|
||||
return {c.name: getattr(self, c.name, None) for c in self.__table__.columns}
|
||||
|
||||
@declared_attr
|
||||
def __tablename__(self) -> str:
|
||||
return self.__name__.lower()
|
||||
from .downloadhistory import DownloadHistory, DownloadFiles
|
||||
from .mediaserver import MediaServerItem
|
||||
from .plugindata import PluginData
|
||||
from .site import Site
|
||||
from .siteicon import SiteIcon
|
||||
from .subscribe import Subscribe
|
||||
from .systemconfig import SystemConfig
|
||||
from .transferhistory import TransferHistory
|
||||
from .user import User
|
||||
|
@ -1,8 +1,7 @@
|
||||
from sqlalchemy import Column, Integer, String, Sequence
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from app.db import db_query
|
||||
from app.db.models import Base, db_update
|
||||
from app.db import db_query, db_update, Base
|
||||
|
||||
|
||||
class DownloadHistory(Base):
|
||||
|
@ -4,8 +4,7 @@ from typing import Optional
|
||||
from sqlalchemy import Column, Integer, String, Sequence
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from app.db import db_query
|
||||
from app.db.models import Base, db_update
|
||||
from app.db import db_query, db_update, Base
|
||||
|
||||
|
||||
class MediaServerItem(Base):
|
||||
|
@ -1,8 +1,7 @@
|
||||
from sqlalchemy import Column, Integer, String, Sequence
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from app.db import db_query
|
||||
from app.db.models import Base, db_update
|
||||
from app.db import db_query, db_update, Base
|
||||
|
||||
|
||||
class PluginData(Base):
|
||||
|
@ -3,8 +3,7 @@ from datetime import datetime
|
||||
from sqlalchemy import Boolean, Column, Integer, String, Sequence
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from app.db import db_query
|
||||
from app.db.models import Base, db_update
|
||||
from app.db import db_query, db_update, Base
|
||||
|
||||
|
||||
class Site(Base):
|
||||
|
@ -1,8 +1,7 @@
|
||||
from sqlalchemy import Column, Integer, String, Sequence
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from app.db import db_query
|
||||
from app.db.models import Base
|
||||
from app.db import db_query, Base
|
||||
|
||||
|
||||
class SiteIcon(Base):
|
||||
|
@ -1,8 +1,7 @@
|
||||
from sqlalchemy import Column, Integer, String, Sequence
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from app.db import db_update, db_query
|
||||
from app.db.models import Base
|
||||
from app.db import db_query, db_update, Base
|
||||
|
||||
|
||||
class Subscribe(Base):
|
||||
|
@ -1,8 +1,7 @@
|
||||
from sqlalchemy import Column, Integer, String, Sequence
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from app.db import db_update, db_query
|
||||
from app.db.models import Base
|
||||
from app.db import db_query, db_update, Base
|
||||
|
||||
|
||||
class SystemConfig(Base):
|
||||
|
@ -3,8 +3,7 @@ import time
|
||||
from sqlalchemy import Column, Integer, String, Sequence, Boolean, func
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from app.db import db_query
|
||||
from app.db.models import Base, db_update
|
||||
from app.db import db_query, db_update, Base
|
||||
|
||||
|
||||
class TransferHistory(Base):
|
||||
|
@ -2,8 +2,7 @@ from sqlalchemy import Boolean, Column, Integer, String, Sequence
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from app.core.security import verify_password
|
||||
from app.db import db_update, db_query
|
||||
from app.db.models import Base
|
||||
from app.db import db_query, db_update, Base
|
||||
|
||||
|
||||
class User(Base):
|
||||
|
@ -40,7 +40,7 @@ class ModuleHelper:
|
||||
@staticmethod
|
||||
def dynamic_import_all_modules(base_path: Path, package_name: str):
|
||||
"""
|
||||
动态导入所有模块到全局对象
|
||||
动态导入目录下所有模块
|
||||
"""
|
||||
modules = []
|
||||
# 遍历文件夹,找到所有模块文件
|
||||
@ -48,14 +48,5 @@ class ModuleHelper:
|
||||
file_name = file.stem
|
||||
if file_name != "__init__":
|
||||
modules.append(file_name)
|
||||
# 保存已有的全局对象
|
||||
existing_globals = set(globals().keys())
|
||||
# 动态导入并添加到全局命名空间
|
||||
for module in modules:
|
||||
full_module_name = f"{package_name}.{module}"
|
||||
import_module = importlib.import_module(full_module_name)
|
||||
module_globals = import_module.__dict__
|
||||
# 仅导入全局对象中不存在的部分
|
||||
new_objects = {name: value for name, value in module_globals.items() if name not in existing_globals}
|
||||
# 更新全局命名空间
|
||||
globals().update(new_objects)
|
||||
full_module_name = f"{package_name}.{file_name}"
|
||||
importlib.import_module(full_module_name)
|
||||
|
@ -5,7 +5,7 @@ from sqlalchemy import pool
|
||||
|
||||
from alembic import context
|
||||
|
||||
from app.db.models import Base
|
||||
from app.db import Base
|
||||
# this is the Alembic Config object, which provides
|
||||
# access to the values within the .ini file in use.
|
||||
config = context.config
|
||||
|
@ -1 +1 @@
|
||||
APP_VERSION = 'v1.4.8-1'
|
||||
APP_VERSION = 'v1.4.8-2'
|
||||
|
Loading…
x
Reference in New Issue
Block a user