1st publish
commit
813171deba
@ -0,0 +1,9 @@
|
||||
**/__pycache__/
|
||||
|
||||
*.pyc
|
||||
|
||||
*.log
|
||||
|
||||
*.idea
|
||||
|
||||
myenv/
|
||||
@ -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,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…
Reference in New Issue