Tổng quan một dòng:
Hành vi của execute()
là như nhau trong tất cả các trường hợp, nhưng họ là 3 phương pháp khác nhau, trong Engine
, Connection
và Session
các lớp học.
Chính xác là gì execute()
:
Để hiểu hành vi của execute()
chúng ta cần nhìn vào Executable
lớp học. Executable
là một siêu lớp cho tất cả các câu lệnh của các loại đối tượng, bao gồm select (), xóa (), update (), insert (), text () - bằng những từ đơn giản nhất có thể, một Executable
cấu trúc biểu thức SQL được hỗ trợ trong SQLAlchemy.
Trong tất cả các trường hợp, execute()
phương thức lấy văn bản SQL hoặc biểu thức SQL được xây dựng, tức là bất kỳ cấu trúc biểu thức SQL nào được hỗ trợ trong SQLAlchemy và trả về kết quả truy vấn (a ResultProxy
- Kết hợp một DB-API
đối tượng con trỏ để cung cấp quyền truy cập dễ dàng hơn vào các cột hàng.)
Để làm rõ hơn nữa (chỉ để làm rõ khái niệm, không phải là một cách tiếp cận được đề xuất) :
Ngoài Engine.execute()
(thực thi không kết nối), Connection.execute()
và Session.execute()
, cũng có thể sử dụng execute()
trực tiếp trên bất kỳ Executable
cấu trúc nào . Các Executable
lớp học có thực hiện riêng của nó trong execute()
- Theo tài liệu chính thức, một dòng mô tả về những gì execute()
làm là " Compile và thực hiện điều nàyExecutable
". Trong trường hợp này, chúng ta cần liên kết rõ ràng Executable
(cấu trúc biểu thức SQL) với một Connection
đối tượng hoặc, Engine
đối tượng (mà hoàn toàn có được một Connection
đối tượng), vì vậy execute()
sẽ biết nơi để thực hiện SQL
.
Ví dụ sau đây cho thấy điều đó tốt - Đưa ra một bảng như dưới đây:
from sqlalchemy import MetaData, Table, Column, Integer
meta = MetaData()
users_table = Table('users', meta,
Column('id', Integer, primary_key=True),
Column('name', String(50)))
Thực hiện rõ ràng tức là Connection.execute()
- chuyển văn bản SQL hoặc biểu thức SQL được xây dựng sang execute()
phương thức Connection
:
engine = create_engine('sqlite:///file.db')
connection = engine.connect()
result = connection.execute(users_table.select())
for row in result:
# ....
connection.close()
Rõ ràng thực thi không kết nối tức là Engine.execute()
- chuyển văn bản SQL hoặc biểu thức SQL được xây dựng trực tiếp sang execute()
phương thức Engine:
engine = create_engine('sqlite:///file.db')
result = engine.execute(users_table.select())
for row in result:
# ....
result.close()
Thực hiện ngầm định tức là Executable.execute()
- cũng không có kết nối và gọi execute()
phương thức của Executable
, nghĩa là, nó gọi execute()
phương thức trực tiếp trên chính SQL
cấu trúc biểu thức (một thể hiện của Executable
).
engine = create_engine('sqlite:///file.db')
meta.bind = engine
result = users_table.select().execute()
for row in result:
# ....
result.close()
Lưu ý: Đã nêu ví dụ thực thi ngầm cho mục đích làm rõ - cách thực hiện này rất không được khuyến nghị - theo tài liệu :
Thực hiện ngầm định là một mô hình sử dụng rất cũ mà trong hầu hết các trường hợp là khó hiểu hơn là hữu ích, và việc sử dụng nó không được khuyến khích. Cả hai mô hình này dường như đều khuyến khích việc sử dụng quá mức các đoạn cắt ngắn ngắn gọn trong thiết kế ứng dụng, điều này dẫn đến các vấn đề về sau.
Những câu hỏi của bạn:
Theo tôi hiểu nếu ai đó sử dụng engine.execute, nó sẽ tạo kết nối, mở phiên (Alchemy quan tâm đến nó cho bạn) và thực hiện truy vấn.
Bạn đúng với phần "nếu ai đó sử dụng engine.execute
nó tạo ra connection
" nhưng không phải cho "mở session
(Alchemy quan tâm đến nó cho bạn) và thực hiện truy vấn" - Sử dụng Engine.execute()
và Connection.execute()
(gần như) một điều tương tự, chính thức, Connection
đối tượng được tạo ra một cách ngầm định và trong trường hợp sau, chúng tôi khởi tạo nó một cách rõ ràng. Điều thực sự xảy ra trong trường hợp này là:
`Engine` object (instantiated via `create_engine()`) -> `Connection` object (instantiated via `engine_instance.connect()`) -> `connection.execute({*SQL expression*})`
Nhưng có một sự khác biệt toàn cầu giữa ba cách thực hiện nhiệm vụ như vậy?
Ở lớp DB, nó giống hệt nhau, tất cả chúng đều thực thi SQL (biểu thức văn bản hoặc các cấu trúc biểu thức SQL khác nhau). Từ quan điểm của ứng dụng, có hai lựa chọn:
- Thực hiện trực tiếp - Sử dụng
Engine.execute()
hoặcConnection.execute()
- Sử dụng
sessions
- xử lý một cách hiệu quả giao dịch như là duy nhất đơn vị-of-nơi làm việc, một cách dễ dàng thông qua session.add()
, session.rollback()
, session.commit()
, session.close()
. Đó là cách để tương tác với DB trong trường hợp ORM tức là các bảng được ánh xạ. Cung cấp nhận dạng_map để nhận ngay các đối tượng đã được truy cập hoặc được tạo / thêm mới trong một yêu cầu.
Session.execute()
cuối cùng sử dụng Connection.execute()
phương thức thực thi câu lệnh để thực thi câu lệnh SQL. Sử dụng Session
đối tượng là cách được khuyến nghị của SQLAlchemy ORM để ứng dụng tương tác với cơ sở dữ liệu.
Một đoạn trích từ các tài liệu :
Điều quan trọng cần lưu ý là khi sử dụng SQLAlchemy ORM, các đối tượng này thường không được truy cập; thay vào đó, đối tượng Phiên được sử dụng làm giao diện cho cơ sở dữ liệu. Tuy nhiên, đối với các ứng dụng được xây dựng xung quanh việc sử dụng trực tiếp các câu lệnh SQL văn bản và / hoặc các cấu trúc biểu thức SQL mà không có sự tham gia của các dịch vụ quản lý cấp cao hơn của ORM, Engine và Connection là vua (và nữ hoàng?) - hãy đọc tiếp.