Câu hỏi Python có hỗ trợ các câu lệnh chuẩn bị MySQL không?


Tôi đã làm việc trên một dự án PHP trước đó, ở đó các câu lệnh chuẩn bị làm cho các truy vấn SELECT nhanh hơn 20%.

Tôi tự hỏi nếu nó hoạt động trên Python? Tôi dường như không thể tìm thấy bất cứ điều gì đặc biệt nói nó làm hay KHÔNG.


43
2017-12-22 17:06


gốc


Xem stackoverflow.com/a/2425500/20774 cho một câu trả lời trực tiếp. TLDR 'no' - James McMahon
Cảm ơn @JamesMcMahon. Bạn có thể gửi bình luận của bạn như là một câu trả lời? - rubayeet
Xong, xem stackoverflow.com/a/17237567/20774 - James McMahon
Tôi đã kiểm tra trong python và? không làm việc (mysql.connector.errors.ProgrammingError: Không phải tất cả các tham số đã được sử dụng trong câu lệnh SQL) nhưng% cách hoạt động hoàn hảo. - alireza
có thể trùng lặp Mô-đun MySQLdb có hỗ trợ các câu lệnh chuẩn bị không? - acrosman


Các câu trả lời:


Câu trả lời trực tiếp, không có nó không.

câu trả lời của joshperry là một lời giải thích tốt về những gì nó làm thay vào đó.

Từ eugene y trả lời cho một câu hỏi tương tự,

Kiểm tra MySQLdb Nhận xét gói:

"Parameterization" được thực hiện trong MySQLdb bằng cách thoát chuỗi và sau đó mù quáng nội suy chúng vào truy vấn, thay vì sử dụng     MYSQL_STMT API. Kết quả là chuỗi unicode phải trải qua hai     biểu diễn trung gian (chuỗi được mã hóa, chuỗi được mã hóa thoát)     trước khi chúng được cơ sở dữ liệu nhận.

Vì vậy, câu trả lời là: Không, nó không.


12
2018-06-21 14:18



Khi bạn nói "python" không, điều đó không chính xác. mô-đun MySQLdb không hỗ trợ các câu lệnh chuẩn bị sẵn sàng, nhưng hàm của chúng ta đã làm. launchpad.net/oursql - underrun
Tôi không chắc liệu tôi có nên cảm thấy lạnh lùng về điều này hay không. Một mặt, tôi cảm thấy một chút bị tẩy não vào việc sử dụng các câu lệnh chuẩn bị (đến từ php / pdo). Mặt khác, đầu vào được thoát ra, điều này rõ ràng là quan trọng, và mysqldb có vẻ như đã xuất hiện trong hầu hết các điểm chuẩn mà tôi đã googled ... Tôi đoán tôi tự hỏi tại sao nó không có; Tôi cho rằng có một lý do chính đáng? - Darragh Enright


Hầu hết các ngôn ngữ cung cấp một cách để làm các câu lệnh tham số chung, Python không khác gì. Khi một truy vấn tham số được sử dụng cơ sở dữ liệu hỗ trợ chuẩn bị báo cáo sẽ tự động làm như vậy.

Trong python, một truy vấn được tham số hóa trông giống như sau:

cursor.execute("SELECT FROM tablename WHERE fieldname = %s", [value])

Kiểu tham số cụ thể có thể khác nhau tùy thuộc vào trình điều khiển của bạn, bạn có thể nhập mô-đun db của mình và sau đó thực hiện print yourmodule.paramstyle.

Từ PEP-249:

paramstyle

       String constant stating the type of parameter marker
       formatting expected by the interface. Possible values are
       [2]:

           'qmark'         Question mark style, 
                           e.g. '...WHERE name=?'
           'numeric'       Numeric, positional style, 
                           e.g. '...WHERE name=:1'
           'named'         Named style, 
                           e.g. '...WHERE name=:name'
           'format'        ANSI C printf format codes, 
                           e.g. '...WHERE name=%s'
           'pyformat'      Python extended format codes, 
                           e.g. '...WHERE name=%(name)s'

53
2017-12-22 17:40



Các chuỗi có bị tự động thoát (truy vấn được thực hiện an toàn) không? - scippie
vâng, họ ... - glglgl
Tôi nghĩ rằng bạn đang đề cập đến SQL tự động trích dẫn, không phải các truy vấn tham số thực tế. - Jeremy Stein
@scippie Có, và không. Mặc dù về mặt kỹ thuật, bạn không cần phải lo lắng về việc thoát và truy vấn vốn đã an toàn, không phải vì các tham số đang được thoát. Lý do là các tham số được gửi đến máy chủ dưới dạng siêu dữ liệu cho truy vấn, không phải trong dòng với câu lệnh truy vấn giống như chúng sẽ là nếu bạn đang làm việc ghép chuỗi ngây thơ. (Điều này đúng nếu cơ sở dữ liệu của bạn hỗ trợ các truy vấn tham số, nếu không, mô-đun cơ sở dữ liệu python sử dụng nối chuỗi mạnh mẽ để mô phỏng chúng) - joshperry
dường như MySQLdb đang gửi từng truy vấn đơn giản mà không "chuẩn bị" (cũng gửi nhiều đồng bằng executes trong executemany), trong khi oursql làm một prepare theo sau bởi một execute (hoặc một executemany, chỉ gửi các tham số / giá trị). launchpad.net/oursql - type


Sau khi xem qua một phương thức execute () của đối tượng Cursor của một gói MySQLdb (một loại gói de-facto để tích hợp với mysql, tôi đoán), có vẻ như, (ít nhất là theo mặc định) nó chỉ làm nội suy chuỗi và trích dẫn chứ không phải truy vấn được tham số thực tế:

if args is not None:
    query = query % db.literal(args)

Nếu đây không phải là nội suy chuỗi, thì đó là gì?

Trong trường hợp thực thi nó thực sự cố gắng thực hiện chèn / thay thế như một câu lệnh duy nhất, trái ngược với việc thực hiện nó trong một vòng lặp. Đó là về nó, không có phép thuật ở đó, có vẻ như. Ít nhất là không phải trong hành vi mặc định của nó.

EDIT: Oh, tôi vừa mới nhận ra, rằng toán tử modulo có thể được overriden, nhưng tôi đã cảm thấy như gian lận và grepped nguồn. Đã không tìm thấy một overriden mod bất cứ nơi nào, mặc dù.


10
2017-12-22 18:04





Sử dụng giao diện SQL theo đề xuất của Amit có thể hoạt động nếu bạn chỉ quan tâm đến hiệu suất. Tuy nhiên, sau đó bạn mất khả năng bảo vệ chống lại SQL injection mà một hỗ trợ Python gốc cho các câu lệnh đã chuẩn bị có thể mang lại. Python 3 có các mô-đun cung cấp hỗ trợ câu lệnh chuẩn bị cho PostgreSQL. Đối với MySQL, "oursql" dường như cung cấp hỗ trợ câu lệnh chuẩn bị đúng (không giả mạo như trong các mô-đun khác).


5
2018-03-29 16:13





Đối với những người chỉ cố gắng tìm ra điều này, VÂNG bạn có thể sử dụng các câu lệnh đã chuẩn bị với Python và MySQL. Chỉ cần sử dụng MySQL Connector / Python từ chính MySQL và khởi tạo con trỏ bên phải:

https://dev.mysql.com/doc/connector-python/en/index.html

https://dev.mysql.com/doc/connector-python/en/connector-python-api-mysqlcursorprepared.html


5
2017-08-13 03:32



Tôi có đọc chính xác cú pháp mạnh mẽ hơn không (với các thay thế có tên) khi bạn làm KHÔNG PHẢI sử dụng cái gọi là báo cáo chuẩn bị? cursor = connection.cursor(); cursor.execute("SELECT * FROM t WHERE name = %(name)s", dict(name='Monty')) - Bob Stein


Không liên quan trực tiếp, nhưng câu trả lời này một câu hỏi khác tại SO bao gồm các chi tiết cú pháp của truy vấn 'templated'. Tôi muốn nói rằng việc tự động thoát sẽ là tính năng quan trọng nhất của họ ...

Về hiệu suất, lưu ý phương pháp executemany trên đối tượng con trỏ. Nó kết hợp một số truy vấn và thực hiện tất cả chúng trong một lần, làm dẫn đến hiệu suất tốt hơn.


1
2017-12-22 17:47



tốt, nó chỉ chạy insert into foo (f1,f2,f3) values (f11,f12,f13),(f21,f22,f23),... và như vậy (thay vì có bạn thực hiện những chèn trong một vòng lặp). Tôi không nói rằng nó không làm tăng hiệu suất mặc dù. - shylent
nhìn vào nguồn MySQLdb có vẻ như .executemany() chỉ vòng lặp hơn .execute() - type


Có một giải pháp!

Bạn có thể sử dụng chúng nếu bạn đặt chúng vào một thủ tục lưu trữ trên máy chủ và gọi chúng như thế này từ python ...

cursor.callproc(Procedurename, args)

Đây là một hướng dẫn nhỏ về các thủ tục lưu sẵn trong mysql và python.

http://www.mysqltutorial.org/calling-mysql-stored-procedures-python/


0
2018-02-19 10:52