DbModel和DbServ

概述

lessweb.plugin.database的DbModel类的子类可以支持sqlalchemy的ORM操作。

dealer中如果参数类型为DbServ,就能获得当前数据库的session句柄。

但请注意不能直接把DbModel对象返回给用户,除非自己实现了相应的Bridge。建议用lessweb.plugin.databaseplugin自带的cast_model()函数,把DbModel对象转换成Model对象,再把Model对象返回给前端。

DbModel原理

from sqlalchemy.ext.declarative import as_declarative, declared_attr

@as_declarative()
class DbModel(object):
    @declared_attr
    def __tablename__(cls):  # 数据库表名默认等于类名
        return cls.__name__

    def __repr__(self):
        return '<DbModel ' + repr(list(self.__dict__.items())) + '>'

DbServ原理

from lessweb import Context
class DatabaseKey(Enum):
    session = 1

class DbServ:
    ctx: Context

    @property
    def db(self) -> Session:
        session = self.ctx.box.get(DatabaseKey.session)
        if session is None:
            raise ValueError('database session not available')
        return session

示例

from sqlalchemy import Column, Integer, Text, String
from lessweb import Service
from lessweb.plugin.databaseplugin import DatabasePlugin, DbServ, DbModel, cast_model

class Book:  # 用途:与前端交互(VO)
    id: int
    name: str
    author: str

class TblBook(DbModel):  # 用途:操作数据库(PO)
    id = Column(Integer, primary_key=True)
    name = Column(Text)
    author = Column(String(64))

def book_detail(serv:Service[DbServ], id:int):
    tblBook = serv().db.query(TblBook).filter(TblBook.id==id).first()
    book = cast_model(Book, tblBook)
    return {'code': 200, 'result': book}

app = Application()
app.add_plugin(DatabasePlugin(...))
app.add_get_mapping('/book/{id}', book_detail)
app.run()