版本 2.7<=, <=3.8
https://pypi.org/project/pymodm/
https://pymodm.readthedocs.io/en/stable/api/index.html#model-fields
github
https://github.com/mongodb/pymodm/
https://github.com/mongodb/pymodm/blob/master/test
example
models.py
from pymodm.connection import connectconnect("mongodb://root:example@192.168.204.129:27017/pintai?authSource=admin", alias="hwmg")import datetime as dtfrom pathlib import Pathfrom pymodm.errors import ValidationErrorfrom pymongo.write_concern import WriteConcernfrom pymodm import MongoModel, fieldsdef must_be_exists(value):if not Path(value).exists():raise ValidationError('指定的路径不存在')class Magazine(MongoModel):name = fields.CharField(required=True, min_length=5, max_length=20)uptime = fields.DateTimeField(default=dt.datetime.utcnow)# path = fields.CharField(required=True, validators=[must_be_exists])class Meta:write_concern = WriteConcern(j =True)connection_alias = 'hwmg'collection_name = 'MAGAZINE'
app.py
from typing import Dictfrom models import Magazinefrom pathlib import Pathfrom pymodm.errors import ValidationErrordef main():# magazine = Magazine(name='安天安全周期第1期', path=r'/home/magazine/001.pdf')# if magazine.is_valid():# magazine.save()m1 = Magazine(name='安天')# if m1.is_valid():# m1.save()# m1.save()try:m1.full_clean()except ValidationError as ve:if isinstance(ve.message, dict):# print(ve.message)for k, v in ve.message.items():print(k,'=' ,v)if __name__ == "__main__":main()
hwmg
import pymongoimport datetime as dtfrom datetime import timedeltafrom flask import requestfrom pathlib import Pathfrom app.models import Magazinefrom pymodm.errors import ValidationErrorfrom commonUtil.file_operation import filename_check, genDir, getSize# from module_server.resource_node.log_func import LOGGERfrom config.config import SECURITY_INFO_FILE_UPLOAD, MAX_ALLOW_UPLOAD_FILE_SIZE, ALLOW_UPLOAD_FILE_SUFFIX# 安全资讯文档上传存放路径 /home/hwmg/log/download/security_infogenDir(SECURITY_INFO_FILE_UPLOAD)def get_sec_info_list(info_data):"""获取查询结果集成员, 生成列表Args:info_data: _description_"""info_list = list()for info in info_data:item = {"id": str(info.pk),"name": info.name,"uploadTime": info.uptime.timestamp(),"url": f"download/security_info/{info.name}"}info_list.append(item)return info_listdef sec_info_get(json_data):"""获取安全资讯信息Args:json_data: _description_"""page = int(json_data.get("page", 1))limit = int(json_data.get("limit", 10))name = json_data.get("name")upload_time = json_data.get("uploadTime")tt = dt.datetime.now() # 查询时间段结束时间, to_time 默认当前ft = tt - timedelta(days=7) # 查询时间段开始时间, from_time 默认7天前payload = dict()if upload_time:from_ts, to_ts = upload_time.split(",")ft = dt.datetime.fromtimestamp(int(from_ts))tt = dt.datetime.fromtimestamp(int(to_ts))find_qs = {"uptime": {"$gte": ft, "$lte": tt}} # 查询条件,时间段-上传时间if name:find_qs.update({"name": {"$regex": name}})# 获取满足查询条件的所有结果, 实现排序result = Magazine.objects.raw(find_qs).order_by([("uptime", pymongo.DESCENDING)])if result.count() < 1:payload['total'] = 0payload['data'] = []else:payload['total'] = result.count()payload['data'] = get_sec_info_list(result.limit(limit).skip((page - 1) * limit))return dict(status=1, message="查询成功", payload = payload)def sec_info_post(json_dat):"""上传安全资讯Args:json_dat: _description_"""sec_info_file = request.files.get("file")if not sec_info_file:return dict(status=-1, message="上传文件未找到")sec_info_filename = filename_check(sec_info_file.filename)sec_info_file_type = Path(sec_info_filename).suffixif sec_info_file_type.lower() not in ALLOW_UPLOAD_FILE_SUFFIX:return dict(status=-1, message="不支持的文件类型")if sec_info_filename == sec_info_file_type:return dict(status=-1, message="文件名称检查异常")try:Magazine.objects.get({"name":sec_info_filename})except Magazine.DoesNotExist:sec_info_file_save_path = SECURITY_INFO_FILE_UPLOAD / sec_info_filenamesec_info_file.save(str(sec_info_file_save_path))if getSize(str(sec_info_file_save_path)) > 1024 * 1024 * MAX_ALLOW_UPLOAD_FILE_SIZE:return dict(status=-1, message="文件大小超过限制 50M")# 数据验证部分返回错误消息try:Magazine(name=sec_info_filename, path=str(sec_info_file_save_path)).save()return dict(status=1, message="上传成功")except ValidationError as ve:for k, v in ve.message.items():if k == "name":return dict(status=-1, message=f"文件名长度不合法: {v}")else:return dict(status=-1, message=f"{v}")else:return dict(status=-1, message="文件已存在")
