From ef938e6d970271a68b72b6f31c742647291e1a03 Mon Sep 17 00:00:00 2001 From: Cxx0822 <1556464090@qq.com> Date: Wed, 24 Sep 2025 20:04:23 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E5=A2=9E=E5=8A=A0Elasticsearch=E5=8A=9F?= =?UTF-8?q?=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/elastic.py | 13 ++++++++ middleware/exceptions.py | 4 +-- requirements.txt | 2 +- schemas/blog_elastic.py | 53 +++++++++++++++++++++++++++++++++ service/blog_elastic_service.py | 36 ++++++++++++++++++++++ 5 files changed, 105 insertions(+), 3 deletions(-) create mode 100644 config/elastic.py create mode 100644 schemas/blog_elastic.py create mode 100644 service/blog_elastic_service.py diff --git a/config/elastic.py b/config/elastic.py new file mode 100644 index 0000000..6d3fdd2 --- /dev/null +++ b/config/elastic.py @@ -0,0 +1,13 @@ +from elasticsearch import Elasticsearch + +from schemas.blog_elastic import BLOG_MAPPING +from config.logging import logger + +ES_HOSTS = ["http://localhost:9200"] +BLOG_INDEX = "blog" + +es = Elasticsearch(hosts=ES_HOSTS) + +if not es.indices.exists(index=BLOG_INDEX): + es.indices.create(index=BLOG_INDEX, body=BLOG_MAPPING) + logger.info(f"Elastic索引 {BLOG_INDEX} 创建成功") diff --git a/middleware/exceptions.py b/middleware/exceptions.py index 1fdbf50..8013846 100644 --- a/middleware/exceptions.py +++ b/middleware/exceptions.py @@ -35,13 +35,13 @@ async def global_exception_handler(request: Request, call_next): except SQLAlchemyError as e: # 记录数据库异常 - #logger.critical(f"数据库异常: {str(e)}", exc_info=True) + logger.critical(f"数据库异常: {str(e)}", exc_info=True) return JSONResponse(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, content={"message": "数据库操作失败", "details": str(e)}) except Exception as e: # 记录未知异常(带堆栈信息) - #logger.critical(f"未知异常: {str(e)}", exc_info=True) + logger.critical(f"未知异常: {str(e)}", exc_info=True) return JSONResponse(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, content={"code": 500, "message": "服务器内部错误", "details": str(e)}) diff --git a/requirements.txt b/requirements.txt index 5fa9cc6..7de8262 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1 +1 @@ -fastapi~=0.115.12 sqlalchemy~=2.0.41 pydantic~=2.11.4 PyJWT~=2.10.1 passlib~=1.7.4 loguru~=0.7.3 pydantic-settings~=2.9.1 pymysql~=1.1.1 python-multipart~=0.0.20 uvicorn~=0.23.0 # pip download -r requirements.txt -d ./packages --only-binary=:all: --platform manylinux2014_x86_64 -i https://pypi.tuna.tsinghua.edu.cn/simple \ No newline at end of file +fastapi~=0.115.12 sqlalchemy~=2.0.41 pydantic~=2.11.4 PyJWT~=2.10.1 passlib~=1.7.4 loguru~=0.7.3 pydantic-settings~=2.9.1 pymysql~=1.1.1 python-multipart~=0.0.20 uvicorn~=0.23.0 elasticsearch~=9.1.1 # pip download -r requirements.txt -d ./packages --only-binary=:all: --platform manylinux2014_x86_64 -i https://pypi.tuna.tsinghua.edu.cn/simple \ No newline at end of file diff --git a/schemas/blog_elastic.py b/schemas/blog_elastic.py new file mode 100644 index 0000000..8258c74 --- /dev/null +++ b/schemas/blog_elastic.py @@ -0,0 +1,53 @@ +from datetime import datetime +from typing import Optional + +from pydantic import BaseModel + + +class BlogElastic(BaseModel): + id: int + title: str + content: str + category: str + + +BLOG_MAPPING = { + "mappings": { + "properties": { + "id": {"type": "integer"}, + "title": { + "type": "text", + "analyzer": "ik_max_word", + "fields": { + "keyword": {"type": "keyword"} + } + }, + "content": { + "type": "text", + "analyzer": "ik_max_word" + }, + "category": { + "type": "keyword" + }, + "createTime": { + "type": "date", + "format": "yyyy-MM-dd HH:mm:ss||epoch_millis" + }, + "updateTime": { + "type": "date", + "format": "yyyy-MM-dd HH:mm:ss||epoch_millis" + } + } + }, + "settings": { + "number_of_shards": 1, + "number_of_replicas": 1, + "analysis": { + "analyzer": { + "ik_max_word": { + "type": "ik_max_word" + } + } + } + } +} diff --git a/service/blog_elastic_service.py b/service/blog_elastic_service.py new file mode 100644 index 0000000..c8d14b0 --- /dev/null +++ b/service/blog_elastic_service.py @@ -0,0 +1,36 @@ +from datetime import datetime + +from config.elastic import es, BLOG_INDEX +from schemas.blog_elastic import BlogElastic + + +def create_blog(blog: BlogElastic) -> bool: + now = datetime.now() + blog.createTime = now + blog.updateTime = now + + es.index( + index=BLOG_INDEX, + id=blog.id, + body=blog.model_dump() + ) + + return True + + +def update_blog(blog: BlogElastic) -> bool: + blog.updateTime = datetime.now() + + es.index( + index=BLOG_INDEX, + id=blog.id, + body=blog.model_dump() + ) + + return True + + +def delete_blog(blog_id: int) -> bool: + es.delete(index=BLOG_INDEX, id=blog_id) + + return True