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}{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")