Làm cách nào để truy vấn cơ sở dữ liệu theo id bằng SqlAlchemy?


95

Tôi cần truy vấn cơ sở dữ liệu SQLAlchemy bằng idcái gì đó tương tự như

User.query.filter_by (tên người dùng = 'peter')

nhưng đối với id. Làm thế nào để tôi làm điều này? [Tìm kiếm trên Google và SO không giúp được gì]


Vui lòng cung cấp thêm chi tiết, chẳng hạn như SQL tương đương hoặc mã giả làm những gì bạn muốn. "Id cơ sở dữ liệu SQLAlchemy" là gì?
Daniel Kluev,

Bảng của bạn có cột id không?
Keith

Câu trả lời:


130

Truy vấn có một hàm get hỗ trợ truy vấn bằng khóa chính của bảng, tôi giả sử là như vậy id.

Ví dụ: để truy vấn một đối tượng có ID là 23:

User.query.get(23)

Lưu ý: Như một số người bình luận và câu trả lời khác đã đề cập, đây không chỉ là cách viết tắt của "Thực hiện lọc truy vấn trên khóa chính". Tùy thuộc vào trạng thái của phiên SQLAlchemy, việc chạy mã này có thể truy vấn cơ sở dữ liệu và trả về một phiên bản mới hoặc nó có thể trả về một phiên bản của đối tượng được truy vấn trước đó trong mã của bạn mà không thực sự truy vấn cơ sở dữ liệu. Nếu bạn chưa làm như vậy, hãy xem xét việc đọc tài liệu về SQLAlchemy Session để hiểu các phân nhánh.


8
Chức năng get cũng hỗ trợ nhiều khóa chính: YourModel.query.get((pk1, pk2)). Chú ý bộ tuple.
marc_aragones

3
Các get()truy vấn chức năng các đối tượng theo khóa chính. Nếu bạn muốn truy vấn bằng id, trước tiên bạn nên đặt idlàm khóa chính.

46

Bạn có thể truy vấn Người dùng có id = 1 như thế này

session.query(User).get(1)


7

get () đôi khi không như bạn mong đợi:

nếu giao dịch của bạn đã được thực hiện:

>>> session.query(User).get(1)
[SQL]: BEGIN (implicit)
[SQL]: SELECT user.id AS user_id, user.name AS user_name, user.fullname AS user_fullname
FROM user
WHERE user.id = ?
[SQL]: (1,)
<User(u'ed', u'Ed Jones')>

nếu bạn đang trong một giao dịch (get () sẽ cung cấp cho bạn đối tượng kết quả trong bộ nhớ mà không cần truy vấn cơ sở dữ liệu):

>>> session.query(User).get(1)
<User(u'ed', u'Ed Jones')>

tốt hơn để sử dụng cái này:

>>> session.query(User.name).filter(User.id == 1).first()
[SQL]: SELECT user.name AS user_name
FROM user
WHERE user.id = ?
 LIMIT ? OFFSET ?
[SQL]: (1, 1, 0)
(u'Edwardo',)

1
Làm thế nào đây là hành vi bất ngờ?
Solomon Ucko

Ý tôi là nếu bạn trong một giao dịch (chưa phải session.commit) thì get()dường như cung cấp cho bạn đối tượng kết quả trong bộ nhớ (mà không thực sự truy vấn cơ sở dữ liệu), nhưng filter().first()sẽ luôn truy vấn cơ sở dữ liệu.
panda912

Có thể thay đổi đồng thời cơ sở dữ liệu trong quá trình giao dịch không? Nếu không, sử dụng gettốt hơn do tăng hiệu quả.
Solomon Ucko

1
như tôi biết sqlalchemy không thể làm việc với những thứ không đồng bộ (dường như chỉ với gevent), và vâng, getnó hiệu quả hơn.
panda912,

Tại sao .first () lại khác với .get () khi có liên quan đến giao dịch? .First () có luôn quay lại cơ sở dữ liệu không? Có phải .get () nhìn vào env hiện tại trước để xem nó có biết id đó hay không?
msouth

1

Nếu bạn sử dụng, tables reflectionbạn có thể gặp sự cố với các giải pháp được đưa ra. (Các giải pháp trước đây ở đây không hiệu quả với tôi).

Những gì tôi đã sử dụng cuối cùng là:

session.query(object._class_).get(id)

( objectđược truy xuất bằng cách phản ánh từ cơ sở dữ liệu, đây là lý do tại sao bạn cần sử dụng .__class__)

Tôi hi vọng cái này giúp được.


0

Đầu tiên, bạn nên đặt idlàm khóa chính.
Sau đó, bạn có thể sử dụng query.get()phương pháp này để truy vấn các đối tượng idđã là khóa chính.

Kể từ khi query.get()phương pháp truy vấn đối tượng bằng khóa chính.
Suy ra từ tài liệu Flask-SQLAlchemy

from flask import Flask
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
db = SQLAlchemy()
db.init_app(app)

class User(db.Model):
    __tablename__ = 'users'
    id = db.Column(db.Integer, primary_key=True)

def test():
    id = 1
    user = User.query.get(id)
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.