Sqlite_Datetime列选择三月的行

In SQLite, use the strftime function to extract components from a date/time value

SELECT *
FROM table
WHERE strftime('%m', datemonth) = '03';

strftime(‘%m’, datemonth): extracts the month part from the datemonth column as a string (with leading zeros for single-digit months).

It is string from time.

strftime 方法按照 “%Y-%m-%d %H:%M:%S” 格式将日期和时间格式化为字符串并打印

strftime 是 python 的方法

now 
import os import socket import sqlite3 import mysql.connector from mysql.connector import Error from datetime import datetime, timedelta from pathlib import Path import time # ================== 配置信息 ================== # 分播机配置:IP -> (LineNumber, SQLite路径) SORTERS = { '192.168.110.56': (1, r'Y:\sorting.db'), '192.168.110.60': (9, r'Z:\sorting.db') } # MySQL 配置 MYSQL_CONFIG = { 'host': 'localhost', 'user': 'admin', 'password': 'gapinyc', 'database': 'board_db', 'auth_plugin': 'mysql_native_password', 'charset': 'utf8mb4' } # 必须按照“从父到子”的依赖顺序排 TABLES = [ 'AppSortingTasks', # 最顶层(无外部依赖) 'AppOperationLogs', # 可能依赖 Tasks,也可能独立 'AppReportRecords', # 通常独立或依赖 Tasks 'AppSortingTaskItems', # 依赖 Tasks 'AppSortingTaskImages', # 通常依赖 Items 或 Tasks 'AppSortingTaskSkus', # 依赖 Items 'AppSortingTaskBoxes' # 可能依赖 Items 或 Tasks ] # 最小时间阈值(只同步此时间之后的数据) MIN_TIME = '2025-09-01 00:00:00' # 轮询间隔(秒) CHECK_INTERVAL = 10 # ================== 工具函数 ================== def is_host_reachable(ip): """检测IP是否可达(通过连接445端口)""" try: sock = socket.create_connection((ip, 445), timeout=3) sock.close() return True except OSError: return False def is_file_accessible(path_str): """检测共享路径上的数据库文件是否存在""" try: db_path = Path(path_str) return db_path.exists() and db_path.is_file() except Exception as e: print(f"[PATH ERROR] {e}") return False def connect_sqlite(db_path): """连接SQLite数据库(只读模式,防锁)""" try: conn = sqlite3.connect(f'file:{db_path}?mode=ro', uri=True, timeout=10.0) return conn except sqlite3.Error as e: print(f"[ERROR] 无法连接SQLite数据库 {db_path}: {e}") return None def connect_mysql(): """连接MySQL数据库""" try: conn = mysql.connector.connect(**MYSQL_CONFIG) if conn.is_connected(): return conn else: print("[ERROR] MySQL连接失败") return None except Error as e: print(f"[ERROR] MySQL连接错误: {e}") return None def truncate_recent_records(cursor, table_name, hours=3): """清空指定表中 creationtime 在最近N小时内的记录""" three_hours_ago = (datetime.now() - timedelta(hours=hours)).strftime('%Y-%m-%d %H:%M:%S') delete_sql = f"DELETE FROM {table_name} WHERE creationtime >= %s" cursor.execute(delete_sql, (three_hours_ago,)) deleted_count = cursor.rowcount if deleted_count > 0: print(f" [TRUNCATE] 表 {table_name} 删除了 {deleted_count} 条 creationtime >= '{three_hours_ago}' 的记录") return deleted_count def sync_table_from_sqlite_to_mysql(sorter_ip, line_number, sqlite_path, mysql_conn, table_name): """从单个SQLite表同步数据到MySQL,并更新所有字段(按正确顺序处理外键依赖)""" sqlite_conn = None mysql_cursor = None try: # 连接SQLite sqlite_conn = connect_sqlite(sqlite_path) if not sqlite_conn: print(f"[FAIL] 无法打开SQLite数据库: {sqlite_path}") return False mysql_cursor = mysql_conn.cursor() # 目标MySQL表名 target_table = f"AI_{table_name}" # --- 读取数据 --- query = f"SELECT * FROM {table_name} WHERE creationtime >= ?" try: rows = list(sqlite_conn.execute(query, (MIN_TIME,))) except sqlite3.Error as e: print(f"[ERROR] 查询SQLite表 {table_name} 出错: {e}") return False if not rows: print(f" ⚠️ 表 {table_name} 无符合 creationtime >= {MIN_TIME} 的数据") return True # 不算失败 print(f" 📥 从 {table_name} 读取到 {len(rows)} 条数据") # 获取sqlite_cursor = sqlite_conn.cursor() sqlite_cursor.execute(f"SELECT * FROM {table_name} LIMIT 1") columns = [desc[0] for desc in sqlite_cursor.description] # 添加 LineNumber all_columns_with_lineno = columns + ['LineNumber'] placeholders = ', '.join(['%s'] * len(all_columns_with_lineno)) insert_columns = ', '.join([f"`{col}`" for col in all_columns_with_lineno]) update_assignments = ', '.join([f"`{col}` = VALUES(`{col}`)" for col in all_columns_with_lineno]) insert_sql = f""" INSERT INTO {target_table} ({insert_columns}) VALUES ({placeholders}) ON DUPLICATE KEY UPDATE {update_assignments} """ # --- 数据准备 --- data_to_insert = [] for row in rows: new_row = list(row) new_row.append(line_number) data_to_insert.append(tuple(new_row)) # --- 关键:开始事务,先删后插 --- mysql_cursor.execute("START TRANSACTION") # 清理最近3小时数据 three_hours_ago = (datetime.now() - timedelta(hours=3)).strftime('%Y-%m-%d %H:%M:%S') delete_sql = f"DELETE FROM {target_table} WHERE creationtime >= %s" mysql_cursor.execute(delete_sql, (three_hours_ago,)) deleted_count = mysql_cursor.rowcount if deleted_count > 0: print(f" [TRUNCATE] 删除 {target_table} 中 creationtime >= '{three_hours_ago}' 的 {deleted_count} 条记录") # 插入新数据 mysql_cursor.executemany(insert_sql, data_to_insert) inserted_count = mysql_cursor.rowcount # 提交事务 mysql_conn.commit() print(f" ✅ 成功向 {target_table} 插入/更新 {inserted_count} 条数据") return True except Exception as e: if mysql_conn: mysql_conn.rollback() print(f"[ERROR] 同步表 {table_name} 时发生异常: {e}") return False finally: if sqlite_conn: sqlite_conn.close() if mysql_cursor: mysql_cursor.close() def sync_single_sorter(sorter_ip, line_number, sqlite_path): """同步一台分播机的所有表""" print(f"\n🔍 开始检查分播机 Line{line_number} ({sorter_ip})...") # 1. 检查网络连通性 if not is_host_reachable(sorter_ip): print(f"❌ 分播机 Line{line_number} ({sorter_ip}) 网络不通") return False print(f"✅ 分播机 Line{line_number} ({sorter_ip}) 网络通畅") # 2. 检查数据库文件存在 if not is_file_accessible(sqlite_path): print(f"❌ 分播机 Line{line_number} 的数据库文件不存在或不可访问: {sqlite_path}") return False print(f"✅ 分播机 Line{line_number} 的数据库文件正常: {sqlite_path}") # 3. 连接MySQL mysql_conn = connect_mysql() if not mysql_conn: print("❌ 无法连接MySQL,跳过本次同步") return False success = True try: for table in TABLES: if not sync_table_from_sqlite_to_mysql(sorter_ip, line_number, sqlite_path, mysql_conn, table): print(f"⚠️ 同步表 {table} 失败") success = False time.sleep(0.2) # 小延迟减轻负载 finally: if mysql_conn.is_connected(): mysql_conn.close() if success: print(f"🟢 分播机 Line{line_number} 所有表同步成功") else: print(f"🔴 分播机 Line{line_number} 部分表同步失败") return success def main_loop(): """主循环:持续定时同步""" print("🚀 分播机数据同步服务已启动...") while True: all_success = True for ip, (line_num, db_path) in SORTERS.items(): if not sync_single_sorter(ip, line_num, db_path): all_success = False status = "全部成功" if all_success else "部分失败" print(f"🔚 本轮同步完成({status}),{CHECK_INTERVAL}秒后进入下一轮...\n") time.sleep(CHECK_INTERVAL) if __name__ == '__main__': main_loop() 从 AppSortingTaskImages 读取到 134633 条数据 所有表只查询12小时前的数据
最新发布
09-19
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

「已注销」

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值