123 lines
4.1 KiB
Python
123 lines
4.1 KiB
Python
#!/usr/bin/env python3
|
||
"""修复 tixianjilu 导入 — 使用指定列名的 INSERT"""
|
||
import re, sys, time, MySQLdb
|
||
|
||
sys.path.insert(0, '.')
|
||
import os; os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'a_long_dianjing.settings')
|
||
import django; django.setup()
|
||
from app_secrets import DATABASE_HOST, DATABASE_PORT, DATABASE_USER, DATABASE_PASSWORD, DATABASE_NAME
|
||
|
||
SQL_FILE = os.path.join(os.path.dirname(__file__), 'xaio_cheng_xu_backup.sql')
|
||
|
||
with open(SQL_FILE, 'r', encoding='utf-8') as f:
|
||
sql_content = f.read()
|
||
|
||
# 旧表字段顺序(SQL INSERT VALUES 的顺序)
|
||
OLD_COLUMNS = [
|
||
'id', 'yonghuid', 'avatar', 'phone', 'nicheng', 'leixing', 'zhifu',
|
||
'skzhanghao', 'jine', 'zhuangtai', 'fangshi', 'shenheid', 'bhliyou',
|
||
'create_time', 'update_time', 'shenhe_danhao', 'shenhe_jilu_id'
|
||
]
|
||
|
||
# 新表字段顺序
|
||
NEW_COLUMNS = [
|
||
'id', 'yonghuid', 'avatar', 'phone', 'nicheng', 'leixing', 'zhifu',
|
||
'skzhanghao', 'jine', 'zhuangtai', 'fangshi', 'shenheid', 'bhliyou',
|
||
'shenhe_jilu_id', 'shenhe_danhao', 'create_time', 'update_time'
|
||
]
|
||
|
||
def parse_sql_value(val_str):
|
||
val_str = val_str.strip()
|
||
if val_str.upper() == 'NULL': return None
|
||
if val_str.startswith("'") and val_str.endswith("'"):
|
||
return val_str[1:-1].replace("\\'", "'").replace("\\\\", "\\")
|
||
try: return int(val_str)
|
||
except ValueError:
|
||
try: return float(val_str)
|
||
except ValueError: return val_str
|
||
|
||
def split_sql_values(values_str):
|
||
values, current, in_quote, escape = [], [], False, False
|
||
for ch in values_str:
|
||
if escape: current.append(ch); escape = False; continue
|
||
if ch == '\\': current.append(ch); escape = True; continue
|
||
if ch == "'": in_quote = not in_quote; current.append(ch); continue
|
||
if ch == ',' and not in_quote: values.append(''.join(current).strip()); current = []; continue
|
||
current.append(ch)
|
||
if current: values.append(''.join(current).strip())
|
||
return [parse_sql_value(v) for v in values]
|
||
|
||
pattern = re.compile(r"INSERT\s+INTO\s+`tixianjilu`\s+VALUES\s*\((.+?)\)\s*;", re.IGNORECASE | re.DOTALL)
|
||
matches = list(pattern.finditer(sql_content))
|
||
print(f"找到 {len(matches)} 条 tixianjilu 记录")
|
||
|
||
conn = MySQLdb.connect(
|
||
host=DATABASE_HOST, port=int(DATABASE_PORT),
|
||
user=DATABASE_USER, password=DATABASE_PASSWORD,
|
||
database=DATABASE_NAME, charset='utf8mb4',
|
||
connect_timeout=10, read_timeout=60, write_timeout=60
|
||
)
|
||
cursor = conn.cursor()
|
||
cursor.execute('SET FOREIGN_KEY_CHECKS = 0')
|
||
|
||
success = 0
|
||
fail = 0
|
||
start = time.time()
|
||
|
||
for i, m in enumerate(matches):
|
||
vals = split_sql_values(m.group(1))
|
||
if len(vals) != len(OLD_COLUMNS):
|
||
fail += 1
|
||
continue
|
||
|
||
# 旧字段 → 值映射
|
||
old_dict = dict(zip(OLD_COLUMNS, vals))
|
||
|
||
# 按新字段顺序构建值列表
|
||
new_vals = []
|
||
for col in NEW_COLUMNS:
|
||
new_vals.append(old_dict.get(col))
|
||
|
||
# 构建 INSERT 语句(指定列名)
|
||
col_names = ', '.join(f'`{c}`' for c in NEW_COLUMNS)
|
||
val_parts = []
|
||
for v in new_vals:
|
||
if v is None:
|
||
val_parts.append('NULL')
|
||
elif isinstance(v, str):
|
||
escaped = conn.escape_string(v)
|
||
if isinstance(escaped, bytes): escaped = escaped.decode()
|
||
val_parts.append(f"'{escaped}'")
|
||
elif isinstance(v, bool):
|
||
val_parts.append('1' if v else '0')
|
||
elif isinstance(v, (int, float)):
|
||
val_parts.append(str(v))
|
||
else:
|
||
val_parts.append('NULL')
|
||
|
||
sql = f"INSERT INTO `tixianjilu` ({col_names}) VALUES ({', '.join(val_parts)})"
|
||
try:
|
||
cursor.execute(sql)
|
||
success += 1
|
||
except Exception as e:
|
||
fail += 1
|
||
if fail <= 3:
|
||
print(f" ERR: {str(e)[:100]}")
|
||
|
||
if success % 100 == 0 and success > 0:
|
||
conn.commit()
|
||
|
||
if (i + 1) % 200 == 0:
|
||
elapsed = time.time() - start
|
||
pct = (i + 1) / len(matches)
|
||
sys.stdout.write(f'\r [{pct:5.1%}] {i+1}/{len(matches)} {elapsed:.0f}s OK:{success} FAIL:{fail}')
|
||
sys.stdout.flush()
|
||
|
||
conn.commit()
|
||
cursor.execute('SET FOREIGN_KEY_CHECKS = 1')
|
||
conn.commit()
|
||
conn.close()
|
||
|
||
elapsed = time.time() - start
|
||
print(f'\n完成: 成功 {success}, 失败 {fail}, 耗时 {elapsed:.0f}s')
|