ayaka.depend.db

  1import json
  2from loguru import logger
  3from pydantic import Field
  4from typing import List, TYPE_CHECKING
  5from typing_extensions import Self
  6from .depend import AyakaDepend
  7from .sql import PrimaryKey, JsonKey, insert_or_replace, create_table, drop_table, insert_or_replace_many, select_many, wrap, db
  8
  9if TYPE_CHECKING:
 10    from .. import AyakaApp
 11
 12
 13class AyakaDB(AyakaDepend):
 14    '''
 15```
 161. 继承时要书写 __table_name__
 172. 如果要把该类放入回调函数的参数表中,则还要编写classmethod async def create_by_app方法
 183. 设置主键需要使用
 19    <name>:<type> = Field(extra=AyakaDB.__primary_key__)
 204. 一些特殊类型的数据请设置其为json形式存取 
 21    <name>:<type> = Field(extra=AyakaDB.__json_key__)
 22    AyakaDB在写入时会自动序列化该数据为字符串,写入数据库,读取时则相反
 235. 若需要编写自定义读写数据方法,可以使用AyakaDB.get_db()方法获取sqlite3.Connection对象
 24```
 25'''
 26    __table_name__ = ""
 27    __primary_key__ = PrimaryKey
 28    __json_key__ = JsonKey
 29    __created__ = False
 30
 31    @classmethod
 32    def _create_by_db_data(cls, data: dict):
 33        props = cls.props()
 34
 35        # 特殊处理json
 36        for k, v in props.items():
 37            extra: dict = v.get("extra", {})
 38            if extra.get("json"):
 39                if k in data:
 40                    data[k] = json.loads(data[k])
 41
 42        return cls(**data)
 43
 44    def __setattr__(self, name, value):
 45        if getattr(self, name) != value:
 46            super().__setattr__(name, value)
 47            self.save()
 48            logger.debug("已自动保存配置更改")
 49
 50    def dict(self, **params):
 51        data = super().dict(**params)
 52        props = self.props()
 53
 54        # 特殊处理json
 55        for k, v in props.items():
 56            extra: dict = v.get("extra", {})
 57            if extra.get("json"):
 58                if k in data:
 59                    data[k] = json.dumps(data[k], ensure_ascii=0)
 60        return data
 61
 62    @classmethod
 63    def drop_table(cls):
 64        drop_table(cls.__table_name__)
 65
 66    @classmethod
 67    def create_table(cls):
 68        '''根据数据类型自动创建表'''
 69        if not cls.__created__:
 70            if not cls.__table_name__:
 71                raise Exception("__table_name__不可为空")
 72            cls.__created__ = True
 73            create_table(cls.__table_name__, cls)
 74
 75    @classmethod
 76    def replace(cls, data: Self):
 77        cls.create_table()
 78        insert_or_replace(cls.__table_name__, data, "replace")
 79
 80    def save(self):
 81        '''写入数据库'''
 82        self.replace(self)
 83
 84    @classmethod
 85    def replace_many(cls, datas: List[Self]):
 86        cls.create_table()
 87        insert_or_replace_many(cls.__table_name__, datas, "replace")
 88
 89    @classmethod
 90    def insert(cls, data: Self):
 91        cls.create_table()
 92        insert_or_replace(cls.__table_name__, data, "insert")
 93
 94    @classmethod
 95    def insert_many(cls, datas: List[Self]):
 96        cls.create_table()
 97        insert_or_replace_many(cls.__table_name__, datas, "insert")
 98
 99    @classmethod
100    def select_many(cls, **params) -> List[Self]:
101        '''按照params的值搜索数据,返回数据列表,若没有符合的数据则返回空列表'''
102        items = []
103        if params:
104            items.extend(f"{k}={wrap(v)}" for k, v in params.items())
105        if items:
106            where = " and ".join(items)
107        else:
108            where = ""
109        cls.create_table()
110        return select_many(cls.__table_name__, cls, where)
111
112    @classmethod
113    def select_one(cls, **params):
114        '''按照params的值搜索数据,返回一项数据,若不存在,则自动根据params创建,创建后自动写入数据库'''
115        datas = cls.select_many(**params)
116        if datas:
117            return datas[0]
118        data = cls(**params)
119        data.save()
120        return data
121
122    @classmethod
123    def get_db(cls):
124        return db
125
126
127class AyakaGroupDB(AyakaDB):
128    '''继承时要书写`__table_name__`
129
130    主键有且仅有 group_id'''
131    group_id: int = Field(extra=AyakaDB.__primary_key__)
132
133    @classmethod
134    async def create_by_app(cls, app: "AyakaApp"):
135        return cls.select_one(group_id=app.group_id)
136
137
138class AyakaUserDB(AyakaDB):
139    '''继承时要书写`__table_name__`
140
141    主键有且仅有 group_id, user_id'''
142    group_id: int = Field(extra=AyakaDB.__primary_key__)
143    user_id: int = Field(extra=AyakaDB.__primary_key__)
144
145    @classmethod
146    async def create_by_app(cls, app: "AyakaApp"):
147        return cls.select_one(
148            group_id=app.group_id,
149            user_id=app.user_id
150        )
class AyakaDB(ayaka.depend.depend.AyakaDepend):
 14class AyakaDB(AyakaDepend):
 15    '''
 16```
 171. 继承时要书写 __table_name__
 182. 如果要把该类放入回调函数的参数表中,则还要编写classmethod async def create_by_app方法
 193. 设置主键需要使用
 20    <name>:<type> = Field(extra=AyakaDB.__primary_key__)
 214. 一些特殊类型的数据请设置其为json形式存取 
 22    <name>:<type> = Field(extra=AyakaDB.__json_key__)
 23    AyakaDB在写入时会自动序列化该数据为字符串,写入数据库,读取时则相反
 245. 若需要编写自定义读写数据方法,可以使用AyakaDB.get_db()方法获取sqlite3.Connection对象
 25```
 26'''
 27    __table_name__ = ""
 28    __primary_key__ = PrimaryKey
 29    __json_key__ = JsonKey
 30    __created__ = False
 31
 32    @classmethod
 33    def _create_by_db_data(cls, data: dict):
 34        props = cls.props()
 35
 36        # 特殊处理json
 37        for k, v in props.items():
 38            extra: dict = v.get("extra", {})
 39            if extra.get("json"):
 40                if k in data:
 41                    data[k] = json.loads(data[k])
 42
 43        return cls(**data)
 44
 45    def __setattr__(self, name, value):
 46        if getattr(self, name) != value:
 47            super().__setattr__(name, value)
 48            self.save()
 49            logger.debug("已自动保存配置更改")
 50
 51    def dict(self, **params):
 52        data = super().dict(**params)
 53        props = self.props()
 54
 55        # 特殊处理json
 56        for k, v in props.items():
 57            extra: dict = v.get("extra", {})
 58            if extra.get("json"):
 59                if k in data:
 60                    data[k] = json.dumps(data[k], ensure_ascii=0)
 61        return data
 62
 63    @classmethod
 64    def drop_table(cls):
 65        drop_table(cls.__table_name__)
 66
 67    @classmethod
 68    def create_table(cls):
 69        '''根据数据类型自动创建表'''
 70        if not cls.__created__:
 71            if not cls.__table_name__:
 72                raise Exception("__table_name__不可为空")
 73            cls.__created__ = True
 74            create_table(cls.__table_name__, cls)
 75
 76    @classmethod
 77    def replace(cls, data: Self):
 78        cls.create_table()
 79        insert_or_replace(cls.__table_name__, data, "replace")
 80
 81    def save(self):
 82        '''写入数据库'''
 83        self.replace(self)
 84
 85    @classmethod
 86    def replace_many(cls, datas: List[Self]):
 87        cls.create_table()
 88        insert_or_replace_many(cls.__table_name__, datas, "replace")
 89
 90    @classmethod
 91    def insert(cls, data: Self):
 92        cls.create_table()
 93        insert_or_replace(cls.__table_name__, data, "insert")
 94
 95    @classmethod
 96    def insert_many(cls, datas: List[Self]):
 97        cls.create_table()
 98        insert_or_replace_many(cls.__table_name__, datas, "insert")
 99
100    @classmethod
101    def select_many(cls, **params) -> List[Self]:
102        '''按照params的值搜索数据,返回数据列表,若没有符合的数据则返回空列表'''
103        items = []
104        if params:
105            items.extend(f"{k}={wrap(v)}" for k, v in params.items())
106        if items:
107            where = " and ".join(items)
108        else:
109            where = ""
110        cls.create_table()
111        return select_many(cls.__table_name__, cls, where)
112
113    @classmethod
114    def select_one(cls, **params):
115        '''按照params的值搜索数据,返回一项数据,若不存在,则自动根据params创建,创建后自动写入数据库'''
116        datas = cls.select_many(**params)
117        if datas:
118            return datas[0]
119        data = cls(**params)
120        data.save()
121        return data
122
123    @classmethod
124    def get_db(cls):
125        return db
1. 继承时要书写 __table_name__
2. 如果要把该类放入回调函数的参数表中,则还要编写classmethod async def create_by_app方法
3. 设置主键需要使用
    <name>:<type> = Field(extra=AyakaDB.__primary_key__)
4. 一些特殊类型的数据请设置其为json形式存取 
    <name>:<type> = Field(extra=AyakaDB.__json_key__)
    AyakaDB在写入时会自动序列化该数据为字符串,写入数据库,读取时则相反
5. 若需要编写自定义读写数据方法,可以使用AyakaDB.get_db()方法获取sqlite3.Connection对象
def dict(self, **params):
51    def dict(self, **params):
52        data = super().dict(**params)
53        props = self.props()
54
55        # 特殊处理json
56        for k, v in props.items():
57            extra: dict = v.get("extra", {})
58            if extra.get("json"):
59                if k in data:
60                    data[k] = json.dumps(data[k], ensure_ascii=0)
61        return data

Generate a dictionary representation of the model, optionally specifying which fields to include or exclude.

@classmethod
def drop_table(cls):
63    @classmethod
64    def drop_table(cls):
65        drop_table(cls.__table_name__)
@classmethod
def create_table(cls):
67    @classmethod
68    def create_table(cls):
69        '''根据数据类型自动创建表'''
70        if not cls.__created__:
71            if not cls.__table_name__:
72                raise Exception("__table_name__不可为空")
73            cls.__created__ = True
74            create_table(cls.__table_name__, cls)

根据数据类型自动创建表

@classmethod
def replace(cls, data: typing_extensions.Self):
76    @classmethod
77    def replace(cls, data: Self):
78        cls.create_table()
79        insert_or_replace(cls.__table_name__, data, "replace")
def save(self):
81    def save(self):
82        '''写入数据库'''
83        self.replace(self)

写入数据库

@classmethod
def replace_many(cls, datas: List[typing_extensions.Self]):
85    @classmethod
86    def replace_many(cls, datas: List[Self]):
87        cls.create_table()
88        insert_or_replace_many(cls.__table_name__, datas, "replace")
@classmethod
def insert(cls, data: typing_extensions.Self):
90    @classmethod
91    def insert(cls, data: Self):
92        cls.create_table()
93        insert_or_replace(cls.__table_name__, data, "insert")
@classmethod
def insert_many(cls, datas: List[typing_extensions.Self]):
95    @classmethod
96    def insert_many(cls, datas: List[Self]):
97        cls.create_table()
98        insert_or_replace_many(cls.__table_name__, datas, "insert")
@classmethod
def select_many(cls, **params) -> List[typing_extensions.Self]:
100    @classmethod
101    def select_many(cls, **params) -> List[Self]:
102        '''按照params的值搜索数据,返回数据列表,若没有符合的数据则返回空列表'''
103        items = []
104        if params:
105            items.extend(f"{k}={wrap(v)}" for k, v in params.items())
106        if items:
107            where = " and ".join(items)
108        else:
109            where = ""
110        cls.create_table()
111        return select_many(cls.__table_name__, cls, where)

按照params的值搜索数据,返回数据列表,若没有符合的数据则返回空列表

@classmethod
def select_one(cls, **params):
113    @classmethod
114    def select_one(cls, **params):
115        '''按照params的值搜索数据,返回一项数据,若不存在,则自动根据params创建,创建后自动写入数据库'''
116        datas = cls.select_many(**params)
117        if datas:
118            return datas[0]
119        data = cls(**params)
120        data.save()
121        return data

按照params的值搜索数据,返回一项数据,若不存在,则自动根据params创建,创建后自动写入数据库

@classmethod
def get_db(cls):
123    @classmethod
124    def get_db(cls):
125        return db
Inherited Members
pydantic.main.BaseModel
BaseModel
json
parse_obj
parse_raw
parse_file
from_orm
construct
copy
schema
schema_json
validate
update_forward_refs
ayaka.depend.depend.AyakaDepend
create_by_app
props
class AyakaGroupDB(AyakaDB):
128class AyakaGroupDB(AyakaDB):
129    '''继承时要书写`__table_name__`
130
131    主键有且仅有 group_id'''
132    group_id: int = Field(extra=AyakaDB.__primary_key__)
133
134    @classmethod
135    async def create_by_app(cls, app: "AyakaApp"):
136        return cls.select_one(group_id=app.group_id)

继承时要书写__table_name__

主键有且仅有 group_id

@classmethod
async def create_by_app(cls, app: ayaka.ayaka.AyakaApp):
134    @classmethod
135    async def create_by_app(cls, app: "AyakaApp"):
136        return cls.select_one(group_id=app.group_id)
Inherited Members
pydantic.main.BaseModel
BaseModel
json
parse_obj
parse_raw
parse_file
from_orm
construct
copy
schema
schema_json
validate
update_forward_refs
AyakaDB
dict
drop_table
create_table
replace
save
replace_many
insert
insert_many
select_many
select_one
get_db
ayaka.depend.depend.AyakaDepend
props
class AyakaUserDB(AyakaDB):
139class AyakaUserDB(AyakaDB):
140    '''继承时要书写`__table_name__`
141
142    主键有且仅有 group_id, user_id'''
143    group_id: int = Field(extra=AyakaDB.__primary_key__)
144    user_id: int = Field(extra=AyakaDB.__primary_key__)
145
146    @classmethod
147    async def create_by_app(cls, app: "AyakaApp"):
148        return cls.select_one(
149            group_id=app.group_id,
150            user_id=app.user_id
151        )

继承时要书写__table_name__

主键有且仅有 group_id, user_id

@classmethod
async def create_by_app(cls, app: ayaka.ayaka.AyakaApp):
146    @classmethod
147    async def create_by_app(cls, app: "AyakaApp"):
148        return cls.select_one(
149            group_id=app.group_id,
150            user_id=app.user_id
151        )
Inherited Members
pydantic.main.BaseModel
BaseModel
json
parse_obj
parse_raw
parse_file
from_orm
construct
copy
schema
schema_json
validate
update_forward_refs
AyakaDB
dict
drop_table
create_table
replace
save
replace_many
insert
insert_many
select_many
select_one
get_db
ayaka.depend.depend.AyakaDepend
props