2016-02-01 18 views
13

Vì vậy, tôi có một kịch bản python mà đi qua khoảng 350.000 đối tượng dữ liệu, và tùy thuộc vào một số xét nghiệm, nó cần phải cập nhật một hàng đại diện cho mỗi một trong những đối tượng trong một db MySQl. Tôi cũng đang sử dụng pymysql như tôi đã có ít rắc rối nhất với nó đặc biệt là khi gửi qua các truy vấn chọn lớn (chọn câu lệnh với mệnh đề where column IN (....) có thể chứa hơn 100.000 giá trị).PyMySQL cập nhật khác nhau trong một truy vấn?

Vì mỗi cập nhật cho mỗi hàng có thể khác nhau, mỗi câu lệnh cập nhật khác nhau. Ví dụ: đối với một hàng, chúng tôi có thể muốn cập nhật first_name nhưng đối với hàng khác, chúng tôi muốn để lại first_name không bị ảnh hưởng và chúng tôi muốn cập nhật last_name.

Đây là lý do tại sao tôi không muốn sử dụng phương thức cursor.executemany() trong một tuyên bố cập nhật chung và sau đó bạn cung cấp giá trị như tôi đã đề cập, mỗi bản cập nhật khác nhau làm việc cho trường hợp của tôi. Tôi cũng không muốn gửi hơn 350.000 báo cáo cập nhật riêng lẻ qua dây. Có anyway tôi có thể gói tất cả các báo cáo cập nhật của tôi với nhau và gửi chúng cùng một lúc?

Tôi đã thử tất cả chúng trong một truy vấn và sử dụng phương thức cursor.execute() nhưng dường như không cập nhật tất cả các hàng.

+0

Có bao nhiêu bản cập nhật khác nhau? tức là bạn đang cập nhật bao nhiêu bảng khác nhau với ba bảng giá trị triệu đô la đó? và có bao nhiêu cột khác nhau trên các bảng đó? tức là nó chỉ là một vài câu lệnh cập nhật khác nhau? –

+1

Có các tùy chọn hữu ích nào khác ngoài truy vấn 'một truy vấn' hoặc 'một phần ba triệu' không? Điều gì sẽ xảy ra nếu dữ liệu được tải vào một 'bảng làm việc' trong cơ sở dữ liệu và thao tác nó từ đó? Cơ sở dữ liệu như chơi với dữ liệu trong bảng? –

+0

@RyanVincent tất cả chỉ cập nhật cùng một bảng, tuy nhiên bảng có 12 cột và mỗi câu lệnh cập nhật có thể cập nhật bất kỳ kết hợp cột nào khác cùng một lúc, từ 1 cột đến 10 cột. –

Trả lời

4

SQL # 1: CREATE TABLE t với bất kỳ cột nào bạn có thể cần phải thay đổi. Tạo tất cả chúng NULL (trái ngược với NOT NULL).

SQL # 2: Thực hiện số lượng lớn INSERT (hoặc LOAD DATA) của tất cả các thay đổi cần thiết. Ví dụ: nếu chỉ thay đổi first_name, hãy điền vào idfirst_name, nhưng có các cột khác NULL.

SQL # 3-14:

UPDATE real_table 
    JOIN t ON t.id = real_table.id 
    SET real_table.first_name = t.first_name 
    WHERE t.first_name IS NOT NULL; 
# ditto for each other column. 

Tất cả SQLs trừ # 1 sẽ tốn nhiều thời gian. Và, kể từ UPDATE cần xây dựng một bản ghi hoàn tác, nó có thể hết thời gian hoặc nếu không có vấn đề. Xem a discussion of chunking nếu cần.

Nếu cần thiết, sử dụng các chức năng như COALESCE(), GREATEST(), IFNULL() vv

Thánh lễ UPDATEs thường ngụ ý thiết kế giản đồ nghèo.

(Nếu Ryan nhảy với một 'Trả lời' thay vì chỉ là một 'Comment', ông có thể sẽ nhận được 'hào phóng'.)

+0

Xin chào Rick, Tôi biết bạn đã trả lời câu hỏi khác của tôi về trình kết nối mysql nhưng tôi gặp lỗi tương tự khi tôi cố gắng tải dữ liệu Local Infile bằng thư viện pymysql. Tôi gặp lỗi Broken Pipe bất kể tôi có chạy mã từ máy của tôi hay máy EC2 nơi DB là DB DB nên tôi nghi ngờ mạng đã bị gián đoạn trong một tuần liên tiếp 'e_bytes raise err.OperationalError (2006, "Máy chủ MySQL đã biến mất (% r)"% (e,)) pymysql.err.OperationalError: (2006, "Máy chủ MySQL đã biến mất (BrokenPipeError (32, 'Broken pipe'))") ' –

5

hiệu suất tốt nhất của bạn sẽ được nếu bạn có thể mã hóa "bài kiểm tra" của bạn vào chính logic SQL, vì vậy bạn có thể đun sôi mọi thứ xuống một số câu lệnh UPDATE. Hoặc ít nhất có được càng nhiều càng tốt được thực hiện theo cách đó, để ít hàng hơn cần phải được cập nhật riêng lẻ.

Ví dụ:

UPDATE tablename set firstname = [some logic] 
WHERE [logic that identifies which rows need the firstname updated]; 

Bạn không mô tả nhiều về các xét nghiệm của bạn, vì vậy thật khó để đảm bảo. Nhưng bạn thường có thể nhận được khá nhiều logic vào mệnh đề WHERE của bạn với một chút công việc.

Một tùy chọn khác là đặt logic của bạn vào quy trình được lưu trữ. Bạn vẫn sẽ làm 350.000 bản cập nhật, nhưng ít nhất chúng không phải là tất cả "đi qua dây".Tôi sẽ sử dụng điều này chỉ như là một phương sách cuối cùng, mặc dù; logic nghiệp vụ phải được lưu giữ trong lớp ứng dụng bất cứ khi nào có thể, và các thủ tục được lưu trữ làm cho ứng dụng của bạn kém di động hơn.

Các vấn đề liên quan