Spaces:
Sleeping
Sleeping
File size: 6,803 Bytes
78dbd3e |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 |
import re
import os
import csv
import sys
# Đường dẫn đến file SQL
sql_file_path = 'datadb.sql'
# Thư mục để lưu các file CSV
output_dir = 'csv_output'
# Tạo thư mục output nếu chưa tồn tại
if not os.path.exists(output_dir):
os.makedirs(output_dir)
# Đọc nội dung file SQL
print("Đang đọc file SQL...")
with open(sql_file_path, 'r', encoding='utf-8') as file:
sql_content = file.read()
# Hàm để trích xuất tên bảng từ câu lệnh CREATE TABLE
def extract_table_name(create_statement):
match = re.search(r'CREATE TABLE `([^`]+)`', create_statement)
if match:
return match.group(1)
return None
# Hàm để trích xuất tên cột từ câu lệnh CREATE TABLE
def extract_columns(create_statement):
# Lấy phần nội dung giữa dấu ngoặc đơn sau CREATE TABLE
match = re.search(r'CREATE TABLE .+?\((.+?)\)[^)]*ENGINE', create_statement, re.DOTALL)
if not match:
return []
columns_text = match.group(1)
# Tìm tất cả các định nghĩa cột (bắt đầu bằng dấu ` và theo sau là kiểu dữ liệu)
column_matches = re.findall(r'`([^`]+)`\s+[^,\n]+', columns_text)
return column_matches
# Hàm để trích xuất dữ liệu từ câu lệnh INSERT
def extract_data(insert_statement):
# Tìm phần VALUES trong câu lệnh INSERT
match = re.search(r'INSERT INTO .+?\s+VALUES\s+(.+?);', insert_statement, re.DOTALL)
if not match:
return []
values_text = match.group(1)
# Tách các bộ giá trị bằng cách phân tích cú pháp thủ công
rows = []
current_row = []
in_string = False
in_parentheses = 0
current_value = ''
for char in values_text:
if char == '\'' and (len(current_value) == 0 or current_value[-1] != '\\'):
in_string = not in_string
current_value += char
elif char == '(' and not in_string:
in_parentheses += 1
if in_parentheses == 1: # Bắt đầu một hàng mới
current_value = ''
else:
current_value += char
elif char == ')' and not in_string:
in_parentheses -= 1
if in_parentheses == 0: # Kết thúc một hàng
if current_value: # Thêm giá trị cuối cùng vào hàng
current_row.append(current_value.strip())
rows.append(current_row.copy()) # Sử dụng copy() để tránh tham chiếu
current_row = []
current_value = ''
else:
current_value += char
elif char == ',' and not in_string and in_parentheses == 1:
current_row.append(current_value.strip())
current_value = ''
else:
current_value += char
# Xử lý các giá trị để loại bỏ dấu nháy không cần thiết
processed_rows = []
for row in rows:
processed_row = []
for value in row:
# Loại bỏ dấu nháy đơn ở đầu và cuối nếu có
if value.startswith('\'') and value.endswith('\''):
value = value[1:-1]
# Xử lý giá trị NULL
elif value.upper() == 'NULL':
value = ''
processed_row.append(value)
processed_rows.append(processed_row)
return processed_rows
print("Đang phân tích cấu trúc SQL...")
# Tìm tất cả các câu lệnh CREATE TABLE
create_table_pattern = r'CREATE TABLE[\s\S]+?ENGINE=\w+[\s\S]+?;'
create_statements = re.findall(create_table_pattern, sql_content)
# Loại bỏ các câu lệnh CREATE TABLE trùng lặp
unique_create_statements = []
seen_tables = set()
for stmt in create_statements:
table_name = extract_table_name(stmt)
if table_name and table_name not in seen_tables:
seen_tables.add(table_name)
unique_create_statements.append(stmt)
print(f"Tìm thấy {len(unique_create_statements)} bảng dữ liệu.")
# Tìm tất cả các câu lệnh INSERT INTO
insert_statements = re.findall(r'INSERT INTO[\s\S]+?;', sql_content)
print(f"Tìm thấy {len(insert_statements)} câu lệnh INSERT.")
# Xóa tất cả các file CSV hiện có trong thư mục output
for file in os.listdir(output_dir):
if file.endswith('.csv'):
os.remove(os.path.join(output_dir, file))
# Xử lý từng bảng
for create_stmt in unique_create_statements:
table_name = extract_table_name(create_stmt)
if not table_name:
continue
print(f"Đang xử lý bảng: {table_name}")
# Trích xuất tên cột
columns = extract_columns(create_stmt)
if not columns:
print(f" Không thể trích xuất cột cho bảng {table_name}")
continue
# Tìm các câu lệnh INSERT cho bảng này
table_inserts = [stmt for stmt in insert_statements if f"INSERT INTO `{table_name}`" in stmt]
# Trích xuất dữ liệu
all_data = []
for insert_stmt in table_inserts:
rows = extract_data(insert_stmt)
all_data.extend(rows)
# Kiểm tra số lượng cột và dữ liệu
for i, row in enumerate(all_data):
if len(row) != len(columns):
print(f" Cảnh báo: Dòng {i+1} có {len(row)} giá trị nhưng có {len(columns)} cột")
# Điều chỉnh số lượng cột nếu cần
if len(row) < len(columns):
row.extend([''] * (len(columns) - len(row)))
else:
row = row[:len(columns)]
all_data[i] = row
# Ghi dữ liệu vào file CSV
csv_file_path = os.path.join(output_dir, f"{table_name}.csv")
with open(csv_file_path, 'w', newline='', encoding='utf-8') as csvfile:
writer = csv.writer(csvfile)
writer.writerow(columns) # Ghi header
writer.writerows(all_data) # Ghi dữ liệu
print(f" Đã tạo file CSV: {csv_file_path} với {len(all_data)} dòng dữ liệu")
print("\nHoàn thành chuyển đổi dữ liệu từ SQL sang CSV!")
print(f"Các file CSV đã được lưu trong thư mục: {os.path.abspath(output_dir)}")
# Hiển thị danh sách các file CSV đã tạo
csv_files = [f for f in os.listdir(output_dir) if f.endswith('.csv')]
print(f"\nDanh sách các file CSV đã tạo ({len(csv_files)} file):")
for csv_file in sorted(csv_files):
file_path = os.path.join(output_dir, csv_file)
file_size = os.path.getsize(file_path)
with open(file_path, 'r', encoding='utf-8') as f:
reader = csv.reader(f)
row_count = sum(1 for _ in reader) - 1 # Trừ đi dòng header
print(f" - {csv_file}: {row_count} dòng dữ liệu, {file_size} bytes") |