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 โดยเฉลี่ยจะยึดเซสชันไว้ในรีจิสทรี "คำขอ" เมื่อใช้รูปแบบเช่นนี้แนวคิด "สร้างเซสชันใหม่ตามคำขอเริ่มต้น" ยังคงดูเหมือนวิธีที่ตรงไปตรงมาที่สุดในการทำให้สิ่งต่างๆตรงไปตรงมา