จะสอบถามฐานข้อมูลโดยใช้ id โดยใช้ SqlAlchemy ได้อย่างไร?


95

ฉันต้องการค้นหาฐานข้อมูล SQLAlchemy โดยidสิ่งที่คล้ายกับ

User.query.filter_by (ชื่อผู้ใช้ = 'ปีเตอร์')

แต่สำหรับ id. ฉันต้องทำอย่างไร [การค้นหาผ่าน Google และ SO ไม่ช่วย]


โปรดระบุรายละเอียดเพิ่มเติมเช่น SQL ที่เทียบเท่าหรือรหัสเทียมที่ทำในสิ่งที่คุณต้องการ "SQLAlchemy database id" คืออะไร?
Daniel Kluev

ตารางของคุณมีคอลัมน์ id หรือไม่?
Keith

คำตอบ:


130

Query มีฟังก์ชัน getที่รองรับการสืบค้นด้วยคีย์หลักของตารางซึ่งฉันคิดว่านั่นidคือ

ตัวอย่างเช่นในการค้นหาวัตถุที่มี ID 23:

User.query.get(23)

หมายเหตุ: ดังที่ผู้แสดงความคิดเห็นและคำตอบอื่น ๆ ได้กล่าวถึงนี่ไม่ใช่แค่ชวเลขสำหรับ "ดำเนินการกรองคำค้นหาบนคีย์หลัก" ขึ้นอยู่กับสถานะของเซสชัน SQLAlchemy การเรียกใช้รหัสนี้อาจสอบถามฐานข้อมูลและส่งคืนอินสแตนซ์ใหม่หรืออาจส่งคืนอินสแตนซ์ของวัตถุที่สอบถามก่อนหน้านี้ในรหัสของคุณโดยไม่ต้องสอบถามฐานข้อมูลจริงๆ หากคุณยังไม่ได้ดำเนินการให้ลองอ่านเอกสารประกอบใน SQLAlchemy Sessionเพื่อทำความเข้าใจเกี่ยวกับการแบ่งส่วน


8
YourModel.query.get((pk1, pk2))ฟังก์ชั่นได้รับนอกจากนี้ยังสนับสนุนคีย์หลักหลาย สังเกตทูเพิล
marc_aragones

3
get()ฟังก์ชั่น queries วัตถุโดยคีย์หลัก หากคุณต้องการสอบถามidคุณควรตั้งค่าidเป็นคีย์หลักก่อน


7

get () ไม่เป็นไปตามที่คุณคาดหวังในบางครั้ง:

หากการทำธุรกรรมของคุณเสร็จสิ้น:

>>> 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')>

หากคุณอยู่ในธุรกรรม (get () จะให้วัตถุผลลัพธ์ในหน่วยความจำโดยไม่ต้องสืบค้นฐานข้อมูล):

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

ดีกว่าที่จะใช้สิ่งนี้:

>>> 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
พฤติกรรมที่ไม่คาดคิดนี้เป็นอย่างไร?
Solomon Ucko

ฉันหมายถึงถ้าคุณทำธุรกรรม (ยังไม่ใช่ session.commit) get()ดูเหมือนว่าจะให้วัตถุผลลัพธ์ในหน่วยความจำแก่คุณ (โดยไม่ต้องค้นหาฐานข้อมูลจริง) แต่filter().first()จะทำการค้นหาฐานข้อมูลเสมอ
panda912

เป็นไปได้หรือไม่ที่จะเปลี่ยนฐานข้อมูลในระหว่างการทำธุรกรรม ถ้าไม่ใช้getจะดีกว่าเนื่องจากประสิทธิภาพที่เพิ่มขึ้น
Solomon Ucko

1
อย่างที่ฉันรู้ว่า sqlalchemy ไม่สามารถทำงานกับสิ่ง async ได้ (ดูเหมือนเฉพาะกับ gevent) และใช่สิ่งgetนี้มีประสิทธิภาพมากกว่า
panda912

เหตุใด. first () จึงแตกต่างจาก. get () เท่าที่เกี่ยวข้องกับธุรกรรม .first () กลับไปที่ฐานข้อมูลเสมอหรือไม่? มันคือ. get () ดู env ปัจจุบันก่อนเพื่อดูว่ามันรู้ว่า id หรืออะไร?
msouth

1

หากคุณใช้tables reflectionคุณอาจมีปัญหากับแนวทางแก้ไขที่ให้ไว้ (วิธีแก้ปัญหาก่อนหน้านี้ไม่ได้ผลสำหรับฉัน)

สิ่งที่ฉันใช้คือ:

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

( objectถูกดึงมาโดยการสะท้อนจากฐานข้อมูลนี่คือเหตุผลที่คุณต้องใช้.__class__)

ฉันหวังว่านี่จะช่วยได้.


0

ขั้นแรกคุณควรตั้งค่าidเป็นคีย์หลัก
จากนั้นคุณสามารถใช้query.get()วิธีการค้นหาวัตถุidที่เป็นคีย์หลักอยู่แล้ว

เนื่องจากquery.get()วิธีการสืบค้นวัตถุด้วยคีย์หลัก
อ้างอิงจากเอกสาร 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)
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.