初始化提交

main
linian 2 weeks ago
parent b684221781
commit 2d1527b17c

164
.gitignore vendored

@ -0,0 +1,164 @@
# ---> Python
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
.pybuilder/
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# poetry
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
#poetry.lock
# pdm
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
#pdm.lock
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
# in version control.
# https://pdm.fming.dev/#use-with-ide
.pdm.toml
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
# pytype static type analyzer
.pytype/
# Cython debug symbols
cython_debug/
# PyCharm
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
.idea/
# Generated data directory by md2word.py
/data/

@ -0,0 +1,37 @@
# 基础镜像
FROM python:3.10
# 设置阿里云的Debian镜像源并安装系统依赖和中文字体
RUN rm -f /etc/apt/sources.list /etc/apt/sources.list.d/* \
&& echo "deb https://mirrors.aliyun.com/debian/ bookworm main" > /etc/apt/sources.list \
&& echo "deb https://mirrors.aliyun.com/debian/ bookworm-updates main" >> /etc/apt/sources.list \
&& apt-get update && apt-get install -y --no-install-recommends \
fonts-wqy-zenhei \
fonts-wqy-microhei \
ttf-wqy-zenhei \
ttf-wqy-microhei \
# 清理 apt 缓存
&& apt-get clean && rm -rf /var/lib/apt/lists/*
# 设置清华大学的pip镜像源
RUN pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
# 设置容器工作目录
WORKDIR /app
# 复制依赖文件
COPY requirements.txt .
# 安装依赖
# taospy 可能会在 aarch64 架构的机器上(如M1/M2 Mac)安装失败,如果遇到问题可以尝试注释掉
RUN pip3 install taospy && \
pip3 install --no-cache-dir -r requirements.txt
# 复制 td_analysis 源代码到工作目录
COPY src/td_analysis /app/src/td_analysis
# 暴露端口
EXPOSE 5002
# 容器启动时运行Python脚本
CMD ["python3", "-u", "src/td_analysis/td_analyzer.py"]

@ -0,0 +1,20 @@
services:
tdengine:
image: tdengine/tdengine
container_name: tdengine
ports:
- "6041:6041"
environment:
- TAOS_FQDN=tdengine
restart: unless-stopped
td_analysis_service:
build: .
container_name: td_analysis_service
ports:
- "5002:5002"
depends_on:
- tdengine
env_file:
- .env
restart: unless-stopped

@ -0,0 +1,10 @@
matplotlib==3.8.4
requests==2.32.3
taospy==2.7.21
pandas>=1.0.0
numpy>=1.18.0
python-dotenv>=0.10.0
fastapi>=0.95.0
uvicorn>=0.21.0
scipy>=1.10.0
openpyxl

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

File diff suppressed because it is too large Load Diff

@ -0,0 +1,68 @@
import os
from dotenv import load_dotenv
import logging
# 配置日志
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)
# 加载.env文件中的环境变量
load_dotenv()
# TDengine数据库配置
TDENGINE_CONFIG = {
'url': os.getenv("TDENGINE_URL", "http://tdengine:6041"),
# 'url': "http://tdengine:6041",
'user': os.getenv("TDENGINE_USER", "root"),
'password': os.getenv("TDENGINE_PASSWORD", "taosdata"),
# 'password': "taosdata",
'database': os.getenv("TDENGINE_DATABASE", "ddllm"),
'timeout': int(os.getenv("TDENGINE_TIMEOUT", "30"))
}
# API服务器配置
API_CONFIG = {
'host': os.getenv("API_HOST", "0.0.0.0"),
# 'host': "0.0.0.0",
'port': int(os.getenv("API_PORT", "5002")),
# 'port': 5002,
# 'base_url': os.getenv("API_BASE_URL", f"http://127.0.0.1:9100")
'base_url': os.getenv("API_BASE_URL", "http://localhost:5002") # 外部访问地址
# 'base_url': "http://localhost:5002" # 外部访问地址
}
# 应用配置
APP_CONFIG = {
'title': os.getenv("APP_TITLE", "变压器振动分析API"),
'description': os.getenv("APP_DESCRIPTION", "基于TDengine的变压器振动数据分析API"),
'version': os.getenv("APP_VERSION", "1.0.0"),
'images_dir': os.getenv("IMAGES_DIR", os.path.join(os.path.dirname(__file__), "static", "images"))
}
# 验证配置是否正确加载
def validate_config():
"""验证配置是否正确加载并打印关键配置信息"""
logger.info("加载配置...")
logger.info(f"TDengine URL: {TDENGINE_CONFIG['url']}")
logger.info(f"TDengine 数据库: {TDENGINE_CONFIG['database']}")
logger.info(f"API服务器地址: {API_CONFIG['base_url']}")
logger.info(f"API服务器端口: {API_CONFIG['port']}")
logger.info(f"图片目录: {APP_CONFIG['images_dir']}")
# 确保图片目录存在
os.makedirs(APP_CONFIG['images_dir'], exist_ok=True)
return True
# 获取图片URL
def get_image_url(file_name):
"""返回图片的完整URL"""
print(f"{API_CONFIG['base_url']}/static/images/{file_name}")
return f"{API_CONFIG['base_url']}/static/images/{file_name}"
if __name__ == "__main__":
validate_config()
print("配置加载完成!")

@ -0,0 +1,124 @@
import taosrest
import pandas as pd
import logging
from td_config import TDENGINE_CONFIG
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)
def connect_to_tdengine():
"""
连接到TDengine数据库
"""
try:
client = taosrest.RestClient(
url=TDENGINE_CONFIG['url'],
user=TDENGINE_CONFIG['user'],
password=TDENGINE_CONFIG['password'],
database=TDENGINE_CONFIG['database'],
timeout=TDENGINE_CONFIG['timeout']
)
logger.info(f"成功连接到TDengine服务器 {TDENGINE_CONFIG['url']}")
return client
except Exception as e:
logger.error(f"连接到TDengine时出错: {str(e)}")
raise
def execute_query(conn, sql):
"""
执行SQL查询并返回结果
"""
try:
logger.info(f"执行查询: {sql}")
# 使用sql方法执行查询
result = conn.sql(sql)
# 将结果转换为DataFrame
if result and isinstance(result, dict) and 'data' in result:
data = result['data']
if data:
df = pd.DataFrame(data)
logger.info(f"查询成功,返回{len(df)}行数据")
return df
logger.info("查询成功,但未返回数据")
return pd.DataFrame()
except Exception as e:
logger.error(f"执行查询时出错: {str(e)}")
raise
def get_database_info(conn):
"""
获取数据库信息
"""
try:
super_tables_df = execute_query(conn, "SHOW STABLES")
tables_df = execute_query(conn, "SHOW TABLES")
db_info = execute_query(conn, f"SHOW {TDENGINE_CONFIG['database']}")
return {
"super_tables": super_tables_df,
"tables": tables_df,
"database_info": db_info
}
except Exception as e:
logger.error(f"获取数据库信息时出错: {str(e)}")
raise
def get_latest_timeseries_data(conn, table_name, limit=1):
"""
获取指定表的最新时序数据
"""
try:
sql = f"SELECT * FROM {table_name} ORDER BY ts DESC LIMIT {limit}"
return execute_query(conn, sql)
except Exception as e:
logger.error(f"获取最新时序数据时出错: {str(e)}")
raise
def test_connection():
"""测试TDengine连接并执行基本查询"""
try:
conn = connect_to_tdengine()
# 测试服务器版本
version_df = execute_query(conn, "SELECT SERVER_VERSION()")
version = version_df.iloc[0, 0] if not version_df.empty else "未知"
logger.info(f"TDengine服务器版本: {version}")
# # 测试数据库列表
# status_df = execute_query(conn, "SHOW DATABASES")
# logger.info(f"找到 {len(status_df)} 个数据库:")
# for idx, row in status_df.iterrows():
# logger.info(f" - {row['name']}")
# # 测试当前数据库的表
# if TDENGINE_CONFIG['database']:
# tables_df = execute_query(conn, "SHOW TABLES")
# logger.info(f"在数据库 '{TDENGINE_CONFIG['database']}' 中找到 {len(tables_df)} 个表")
# if not tables_df.empty:
# for idx, row in tables_df.iterrows():
# logger.info(f" - {row['table_name']} (创建于 {row['created_time']})")
# logger.info("连接测试完成")
return True
except Exception as e:
logger.error(f"连接测试失败: {str(e)}")
return False
if __name__ == "__main__":
print("=" * 60)
print(f"TDengine连接测试 - {TDENGINE_CONFIG['url']}")
print("=" * 60)
if test_connection():
print("\n✓ 连接测试成功!")
else:
print("\n✗ 连接测试失败,请检查连接参数和错误日志。")
print("\n提示: 要使用此模块请先安装TDengine REST客户端:")
print("pip install taosrest")
Loading…
Cancel
Save