1st publish

main
huangjinysf 6 months ago
commit 813171deba

9
.gitignore vendored

@ -0,0 +1,9 @@
**/__pycache__/
*.pyc
*.log
*.idea
myenv/

@ -0,0 +1,20 @@
FROM python:3.11
ENV LANG C.UTF-8
ENV LC_ALL C.UTF-8
ENV LANGUAGE C.UTF-8
WORKDIR /app
COPY requirements.txt .
COPY ./app .
# 如果有requirements.txt取消下面的注释
# 使用 BuildKit 缓存挂载(避免重复下载 pip 包)
RUN --mount=type=cache,target=/root/.cache/pip \
pip install --no-cache-dir -r requirements.txt -i https://mirrors.aliyun.com/pypi/simple/
# pip install -r requirements.txt -i https://mirrors.aliyun.com/pypi/simple/
CMD ["python", "db_test.py"]

@ -0,0 +1,24 @@
import logging
import time
import os
# 确保日志目录存在
log_dir = 'logs'
os.makedirs(log_dir, exist_ok=True)
# 配置日志
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s',
handlers=[
logging.FileHandler(f'{log_dir}/app.log'),
logging.StreamHandler()
]
)
logger = logging.getLogger(__name__)
if __name__ == '__main__':
while True:
logger.info("Hello World from Docker Compose!")
time.sleep(5)

@ -0,0 +1,98 @@
from datetime import datetime
import logging
import time
import os
import sys
import locale
import mysql.connector
from mysql.connector import Error
# 强制系统使用UTF-8
sys.stdout.reconfigure(encoding='utf-8')
sys.stderr.reconfigure(encoding='utf-8')
locale.setlocale(locale.LC_ALL, 'C.UTF-8')
if sys.platform != 'win32':
os.environ['TZ'] = 'Asia/Shanghai'
time.tzset() # 重新加载时区配置
# 确保日志目录存在
log_dir = 'logs'
os.makedirs(log_dir, exist_ok=True)
# 配置日志
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s',
handlers=[
logging.FileHandler(f'{log_dir}/app.log', encoding='utf-8'),
logging.StreamHandler()
]
)
class CSTFormatter(logging.Formatter):
def formatTime(self, record, datefmt=None):
ct = datetime.fromtimestamp(record.created).astimezone()
if datefmt:
s = ct.strftime(datefmt)
else:
t = ct.strftime("%Y-%m-%d %H:%M:%S")
s = "%s,%03d" % (t, record.msecs)
return s
logger = logging.getLogger(__name__)
def get_table_count(db_name):
try:
# 连接到MySQL数据库
connection = mysql.connector.connect(
host='106.227.91.181',
user='root', # 替换为您的MySQL用户名
password='cuixing@HuaerdaMySQL', # 替换为您的MySQL密码
database='huaerdames_cloud'
# host= 'localhost',
# user='root', # 替换为您的MySQL用户名
# password='root', # 替换为您的MySQL密码
# database='huaerdames_cloud'
)
if connection.is_connected():
cursor = connection.cursor()
# 获取所有表名
cursor.execute(f"SHOW TABLES FROM {db_name}")
tables = cursor.fetchall()
# 统计每个表的记录数
table_counts = {}
for table in tables:
table_name = table[0]
cursor.execute(f"SELECT COUNT(*) FROM {table_name}")
count = cursor.fetchone()[0]
table_counts[table_name] = count
return table_counts
except Error as e:
logger.error(f"数据库连接错误: {e}")
return None
finally:
if connection.is_connected():
cursor.close()
connection.close()
if __name__ == '__main__':
# 统计表数量
db_name = 'huaerdames_cloud'
table_counts = get_table_count(db_name)
if table_counts:
logger.info(f"数据库 '{db_name}' 表统计:")
for table, count in table_counts.items():
logger.info(f"表名: {table}, 记录数: {count}")
logger.info(f"总表数: {len(table_counts)}")
else:
logger.warning("未能获取表统计信息")

@ -0,0 +1,20 @@
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from config.settings import DB_CONFIG
from urllib.parse import quote_plus
DATABASE_URL = (
f"mysql+pymysql://{DB_CONFIG['user']}:{quote_plus(DB_CONFIG['password'])}"
f"@{DB_CONFIG['host']}:{DB_CONFIG['port']}/{DB_CONFIG['database']}"
)
engine = create_engine(
DATABASE_URL,
pool_size=5, # 默认 5可根据并发调整
max_overflow=20, # 超过 pool_size 后最大溢出连接数
pool_timeout=30, # 等待连接的超时时间
pool_recycle=1800, # 防止 MySQL server timeout
pool_pre_ping=True # 检查连接是否可用
)
SessionLocal = sessionmaker(bind=engine, autoflush=False, autocommit=False)

@ -0,0 +1,7 @@
DB_CONFIG = {
"user": "root",
"password": "cuixing@HuaerdaMySQL",
"host": "106.227.91.181",
"port": 3306,
"database": "huaerdames_cloud"
}

@ -0,0 +1,16 @@
version: '3.11'
services:
python-logger:
build:
context: .
dockerfile: Dockerfile
# 启用 BuildKit 缓存
args:
- BUILDKIT_INLINE_CACHE=1 # 允许缓存复用
container_name: my-python-logger
volumes:
- ./logs:/app/logs
working_dir: /app
#restart: unless-stopped
restart: on-failure

@ -0,0 +1,42 @@
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, BigInteger, String, DECIMAL, DateTime, Boolean
Base = declarative_base()
class WmsIngredientsLog(Base):
__tablename__ = 'wms_ingredients_log'
id = Column(BigInteger, primary_key=True, autoincrement=True)
net_weight = Column(DECIMAL(24,2))
is_deleted = Column(Boolean, default=False)
create_time = Column(DateTime)
# 其他字段省略...
code_sn = Column(String(50))
ingredients_id = Column(BigInteger)
ingredients_name = Column(String(90))
manufacturer_id = Column(BigInteger)
manufacturer_name = Column(String(90))
part_number = Column(String(50))
lot_number = Column(String(50))
product_id = Column(BigInteger)
product_name = Column(String(90))
item_specification = Column(String(90))
item_id = Column(BigInteger)
net_weight = Column(DECIMAL(24,2))
gross_weight = Column(DECIMAL(24,2))
tare_weight = Column(DECIMAL(24,2), default=0.00)
measure_id = Column(BigInteger)
measure_name = Column(String(90))
job_number = Column(String(90))
status = Column(String(1))
is_deleted = Column(Boolean, default=False)
version = Column(BigInteger, default=0)
create_by = Column(String(100))
create_time = Column(DateTime)
update_by = Column(String(100))
update_time = Column(DateTime)
attr1 = Column(String(255))
attr2 = Column(BigInteger)
# attr3 JSON 可加 sqlalchemy.dialects.mysql.JSON
order_weight = Column(DECIMAL(24,2))
is_documents = Column(String(1))

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

@ -0,0 +1,15 @@
import matplotlib.pyplot as plt
from service.wms_ingredients_service import WmsIngredientsService
service = WmsIngredientsService()
df = service.get_monthly_weight_df()
plt.figure(figsize=(12, 6))
plt.plot(df["month"], df["total_weight"], marker="o")
plt.title("Monthly Net Weight Statistics")
plt.xlabel("Month")
plt.ylabel("Total Net Weight")
plt.grid(True)
plt.xticks(rotation=45)
plt.tight_layout()
plt.show()

@ -0,0 +1,30 @@
from config.database import SessionLocal
from sqlalchemy import text
class BaseRepository:
def __init__(self):
self.session = SessionLocal()
def add(self, obj):
self.session.add(obj)
self.session.commit()
self.session.refresh(obj)
return obj
def delete(self, obj):
self.session.delete(obj)
self.session.commit()
def get_by_id(self, entity, id_):
return self.session.query(entity).get(id_)
def list_all(self, entity):
return self.session.query(entity).all()
def execute_sql(self, sql, params=None):
"""执行原生 SQL"""
result = self.session.execute(text(sql), params or {})
return result.fetchall()
def close(self):
self.session.close()

@ -0,0 +1,26 @@
from repository.base_repository import BaseRepository
from entity.wms_ingredients_log import WmsIngredientsLog
class WmsIngredientsLogRepository(BaseRepository):
def get_monthly_net_weight(self):
sql = """
SELECT DATE_FORMAT(create_time, '%Y-%m') AS month,
SUM(net_weight) AS total_weight
FROM wms_ingredients_log
WHERE is_deleted = 0
AND net_weight IS NOT NULL
AND create_time IS NOT NULL
GROUP BY DATE_FORMAT(create_time, '%Y-%m')
ORDER BY month
"""
return self.execute_sql(sql)
def get_ingredients_log_by_code_sn(self, code_sn: str):
sql = """
SELECT *
FROM wms_ingredients_log
WHERE code_sn = :code_sn
AND is_deleted = 0
LIMIT 1
"""
rows = self.execute_sql(sql, {"code_sn": code_sn})
return rows[0] if rows else None

Binary file not shown.

@ -0,0 +1,14 @@
import pandas as pd
from repository.wms_ingredients_log_repository import WmsIngredientsLogRepository
class WmsIngredientsService:
def __init__(self):
self.repo = WmsIngredientsLogRepository()
def get_monthly_weight_df(self):
rows = self.repo.get_monthly_net_weight()
df = pd.DataFrame(rows, columns=["month", "total_weight"])
df["month"] = pd.to_datetime(df["month"])
return df
def get_ingredients_log_by_code_sn(self, code_sn: str):
return self.repo.get_ingredients_log_by_code_sn(code_sn)

@ -0,0 +1,6 @@
from service.wms_ingredients_service import WmsIngredientsService
service = WmsIngredientsService()
record = service.get_ingredients_log_by_code_sn("ITEM_2508290093006")
print(record)

@ -0,0 +1,65 @@
import mysql.connector
import pandas as pd
import matplotlib.pyplot as plt
from datetime import datetime
# Database connection
try:
cloud_conn = mysql.connector.connect(
host='106.227.91.181',
database='huaerdames_cloud',
port=3306,
user='root',
password='cuixing@HuaerdaMySQL'
)
# Query to get net_weight by month
query = """
SELECT
DATE_FORMAT(create_time, '%Y-%m') as month,
SUM(net_weight) as total_weight
FROM wms_ingredients_log
WHERE is_deleted = 0
AND net_weight IS NOT NULL
AND create_time IS NOT NULL
GROUP BY DATE_FORMAT(create_time, '%Y-%m')
ORDER BY month
"""
# Execute query and load data into DataFrame
df = pd.read_sql(query, cloud_conn)
# Close database connection
cloud_conn.close()
# Convert month to datetime for better plotting
df['month'] = pd.to_datetime(df['month'])
# Create the plot
plt.figure(figsize=(12, 6))
plt.plot(df['month'], df['total_weight'], marker='o')
# Customize the plot
plt.title('Monthly Net Weight Statistics', fontsize=14)
plt.xlabel('Month', fontsize=12)
plt.ylabel('Total Net Weight', fontsize=12)
plt.grid(True)
# Rotate x-axis labels for better readability
plt.xticks(rotation=45)
# Adjust layout to prevent label cutoff
plt.tight_layout()
# Save the plot
plt.savefig('monthly_weight_plot.png')
# Show the plot
plt.show()
except mysql.connector.Error as err:
print(f"Database error: {err}")
except Exception as e:
print(f"Error: {e}")
Loading…
Cancel
Save