sessionmaker()
เป็นโรงงานที่สนับสนุนให้วางตัวเลือกการกำหนดค่าสำหรับการสร้างSession
วัตถุใหม่ในที่เดียว เป็นทางเลือกที่คุณสามารถโทรหาได้ง่าย ๆSession(bind=engine, expire_on_commit=False)
เมื่อใดก็ตามที่คุณต้องการสิ่งใหม่Session
ยกเว้นว่ามันใช้งานได้และซ้ำซ้อนและฉันต้องการหยุดการแพร่กระจายของ "ตัวช่วย" ขนาดเล็กที่แต่ละคนเข้าหาปัญหาของความซ้ำซ้อนนี้ในใหม่ และวิธีที่สับสนมากขึ้น
ดังนั้นsessionmaker()
เป็นเพียงเครื่องมือที่จะช่วยคุณสร้างSession
วัตถุเมื่อคุณต้องการ
ส่วนถัดไป ฉันคิดว่าคำถามคืออะไรคือความแตกต่างระหว่างการสร้างสิ่งใหม่Session()
ในหลาย ๆ จุดกับการใช้เพียงครั้งเดียวตลอดทาง คำตอบไม่มาก Session
เป็นคอนเทนเนอร์สำหรับวัตถุทั้งหมดที่คุณใส่ลงไปจากนั้นก็จะติดตามธุรกรรมที่เปิดอยู่ ในขณะที่คุณโทรrollback()
หรือcommit()
ธุรกรรมสิ้นสุดลงและSession
ไม่มีการเชื่อมต่อกับฐานข้อมูลจนกว่าจะถูกเรียกให้ปล่อย SQL อีกครั้ง ลิงก์ที่เก็บไว้กับอ็อบเจ็กต์ที่แมปของคุณมีการอ้างอิงที่อ่อนแอหากอ็อบเจ็กต์นั้นสะอาดจากการเปลี่ยนแปลงที่รอดำเนินการดังนั้นแม้ว่าในกรณีนี้Session
จะทำให้ตัวเองว่างเปล่ากลับสู่สถานะใหม่ล่าสุดเมื่อแอปพลิเคชันของคุณสูญเสียการอ้างอิงทั้งหมดไปยังอ็อบเจ็กต์ที่แมป หากคุณปล่อยให้เป็นค่าเริ่มต้น"expire_on_commit"
จากนั้นวัตถุทั้งหมดจะหมดอายุหลังจากการคอมมิต หากสิ่งนั้นSession
ค้างอยู่เป็นเวลาห้าหรือยี่สิบนาทีและมีการเปลี่ยนแปลงทุกอย่างในฐานข้อมูลในครั้งต่อไปที่คุณใช้งานมันจะโหลดสถานะใหม่ทั้งหมดในครั้งต่อไปที่คุณเข้าถึงวัตถุเหล่านั้นแม้ว่าพวกเขาจะอยู่ในหน่วยความจำก็ตาม เป็นเวลายี่สิบนาที
ในเว็บแอปพลิเคชันเรามักจะพูดว่าเฮ้ทำไมคุณไม่สร้างแบรนด์ใหม่Session
สำหรับแต่ละคำขอแทนที่จะใช้อันเดิมซ้ำแล้วซ้ำเล่า แนวทางปฏิบัตินี้ช่วยให้มั่นใจได้ว่าคำขอใหม่เริ่ม "สะอาด" หากวัตถุบางอย่างจากคำขอก่อนหน้านี้ยังไม่ได้รับการเก็บรวบรวมขยะและหากคุณปิดไป"expire_on_commit"
แล้วบางทีสถานะบางอย่างจากคำขอก่อนหน้านี้ยังคงค้างอยู่และสถานะนั้นอาจค่อนข้างเก่า หากคุณระมัดระวังที่จะexpire_on_commit
เปิดเครื่องทิ้งไว้และโทรออกอย่างแน่นอนcommit()
หรือrollback()
เมื่อขอสิ้นสุดก็ไม่เป็นไร แต่ถ้าคุณเริ่มต้นด้วยแบรนด์ใหม่Session
ก็ไม่มีแม้แต่คำถามใด ๆ ที่คุณกำลังเริ่มต้นใหม่ ดังนั้นความคิดที่จะเริ่มต้นแต่ละคำขอด้วยไฟล์Session
เป็นเพียงวิธีที่ง่ายที่สุดในการตรวจสอบให้แน่ใจว่าคุณเริ่มต้นใหม่และใช้ประโยชน์จากexpire_on_commit
ทางเลือกได้มากเนื่องจากแฟล็กนี้อาจมี SQL เพิ่มเติมจำนวนมากสำหรับการดำเนินการที่เรียกcommit()
อยู่ระหว่างชุดการดำเนินการ ไม่แน่ใจว่าจะตอบคำถามของคุณได้หรือไม่
รอบต่อไปคือสิ่งที่คุณพูดถึงเกี่ยวกับเธรด หากแอปของคุณเป็นแบบมัลติเธรดเราขอแนะนำให้ตรวจสอบว่าการSession
ใช้งานอยู่ในพื้นที่ของ ... scoped_session()
โดยค่าเริ่มต้นจะทำให้เป็นแบบโลคัลสำหรับเธรดปัจจุบัน ในแอปพลิเคชันเว็บในท้องถิ่นตามคำขอนั้นดีกว่าในความเป็นจริง Flask-SQLAlchemy จะส่ง "ฟังก์ชันขอบเขต" ที่กำหนดเองไปscoped_session()
เพื่อให้คุณได้รับเซสชันที่กำหนดขอบเขตคำขอ แอปพลิเคชัน Pyramid โดยเฉลี่ยจะยึดเซสชันไว้ในรีจิสทรี "คำขอ" เมื่อใช้รูปแบบเช่นนี้แนวคิด "สร้างเซสชันใหม่ตามคำขอเริ่มต้น" ยังคงดูเหมือนวิธีที่ตรงไปตรงมาที่สุดในการทำให้สิ่งต่างๆตรงไปตรงมา