Nplusone เป็นห้องสมุดสำหรับตรวจจับปัญหา N+1 ใน Python ORMS รวมถึง Sqlalchemy, Peewee และ Django Orm
ไลบรารีการแมปวัตถุที่เกี่ยวข้อง (ORM) จำนวนมากเริ่มต้นที่จะโหลดขี้เกียจสำหรับความสัมพันธ์ รูปแบบนี้สามารถมีประสิทธิภาพเมื่อมีการเข้าถึงแถวที่เกี่ยวข้อง แต่ไม่ค่อยมีการเข้าถึง แต่จะไม่มีประสิทธิภาพอย่างรวดเร็วเนื่องจากความสัมพันธ์ได้รับการเข้าถึงบ่อยขึ้น ในกรณีเหล่านี้การโหลดแถวที่เกี่ยวข้องอย่างกระตือรือร้นโดยใช้ JOIN
อาจเป็นนักแสดงได้มากขึ้น น่าเสียดายที่การทำความเข้าใจเมื่อใดที่จะใช้ขี้เกียจเมื่อเทียบกับความกระตือรือร้นในการโหลดอาจเป็นเรื่องที่ท้าทาย: คุณอาจไม่สังเกตเห็นปัญหาจนกว่าแอปของคุณจะชะลอการรวบรวมข้อมูล
nplusone
เป็นเครื่องมือในการทำโปรไฟล์ ORM เพื่อช่วยวินิจฉัยและปรับปรุงประสิทธิภาพที่ไม่ดีที่เกิดจากการโหลดขี้เกียจที่ไม่เหมาะสม nplusone
ตรวจสอบแอปพลิเคชันโดยใช้ django หรือ sqlalchemy และส่งการแจ้งเตือนเมื่อปล่อยโหลดขี้เกียจราคาแพง มันสามารถระบุแอตทริบิวต์ความสัมพันธ์ที่กระทำผิดและบรรทัดเฉพาะของรหัสที่อยู่เบื้องหลังปัญหาและแนะนำให้แก้ไขเพื่อประสิทธิภาพที่ดีขึ้น
nplusone
ยังตรวจพบการโหลดที่กระตือรือร้นที่ไม่เหมาะสมสำหรับ Flask-Sqlalchemy และ Django Orm ปล่อยคำเตือนเมื่อมีการโหลดข้อมูลที่เกี่ยวข้องอย่างกระตือรือร้น แต่ไม่เคยเข้าถึงได้ภายในคำขอปัจจุบัน
PIP Install -u nplusone
nplusone รองรับ Python> = 2.7 หรือ> = 3.3
หมายเหตุ: ควรใช้ nplusone
สำหรับการพัฒนาเท่านั้นและไม่ควรนำไปใช้กับสภาพแวดล้อมการผลิต
หมายเหตุ: nplusone
รองรับ django> = 1.8
เพิ่ม nplusone
ใน INSTALLED_APPS
:
ติดตั้ง _apps = ( - 'nplusone.ext.django' -
เพิ่ม NPlusOneMiddleware
:
มิดเดิลแวร์ = ( 'nplusone.ext.django.nplusonemiddleware' - -
เลือกกำหนดค่าการตั้งค่าการบันทึก:
nplusone_logger = logging.getLogger ('nplusone') nplusone_log_level = logging.warn
กำหนดค่าตัวจัดการการบันทึก:
การบันทึก = { 'เวอร์ชัน': 1, 'ตัวจัดการ': { 'คอนโซล': { 'class': 'logging.streamhandler' - - 'คนตัดไม้': { 'nplusone': { 'ตัวจัดการ': ['คอนโซล'], 'ระดับ': 'เตือน', - - -
เมื่อแอปของคุณโหลดข้อมูลอย่างเกียจคร้าน nplusone
จะปล่อยข้อความบันทึก:
ตรวจพบการสืบค้น n+1 ที่มีศักยภาพใน `<mode>. <field>`
พิจารณาใช้ select_related หรือ prefetch_related ในกรณีนี้
เมื่อแอปของคุณโหลดข้อมูลที่เกี่ยวข้องอย่างกระตือรือร้นโดยไม่ต้องเข้าถึง nplusone
จะบันทึกคำเตือน:
ตรวจพบโหลดที่ไม่จำเป็นที่ไม่จำเป็นใน `<mode>. <field>`
ห่อแอปพลิเคชันด้วย NPlusOne
:
จาก Flask Import Flask จาก nplusone.ext.flask_sqlalchemy นำเข้า nplusone App = Flask (__ name__) nplusone (แอพ)
เลือกกำหนดค่าการตั้งค่าการบันทึก:
App = Flask (__ name__) app.config ['nplusone_logger'] = logging.getLogger ('app.nplusone') app.config ['nplusone_log_level'] = logging.error nplusone (แอพ)
เมื่อแอปของคุณโหลดข้อมูลอย่างเกียจคร้าน nplusone
จะปล่อยข้อความบันทึก:
ตรวจพบการสืบค้น n+1 ที่มีศักยภาพใน `<mode>. <field>`
พิจารณาใช้ subqueryload
หรือ joinedload
ในกรณีนี้ ดูคำแนะนำของ Sqlalchemy เกี่ยวกับการโหลดความสัมพันธ์สำหรับเอกสารที่สมบูรณ์
เมื่อแอปของคุณโหลดข้อมูลที่เกี่ยวข้องอย่างกระตือรือร้นโดยไม่ต้องเข้าถึง nplusone
จะบันทึกคำเตือน:
ตรวจพบโหลดที่ไม่จำเป็นที่ไม่จำเป็นใน `<mode>. <field>`
สำหรับเฟรมเวิร์กอื่น ๆ ที่เป็นไปตามข้อกำหนด WSGI ให้ห่อแอปพลิเคชันของคุณด้วย nplusonemiddleware คุณต้องนำเข้าส่วนขยาย nplusone
ที่เกี่ยวข้องสำหรับ ORM ของคุณ:
นำเข้าขวด จาก nplusone.ext.wsgi นำเข้า nplusonemiddleware นำเข้า nplusone.ext.sqlalchemy app = nplusonemiddleware (bottle.app ())
การบูรณาการข้างต้นจะเชื่อมโยงกับวัฏจักรการตอบสนองการร้องขอ หากต้องการใช้ nplusone
นอกบริบทของคำขอ HTTP ให้ใช้ตัวจัดการบริบท Profiler
: คุณต้องนำเข้าส่วนขยาย nplusone
ที่เกี่ยวข้องสำหรับ ORM ของคุณ:
จาก nplusone.core นำเข้า Profiler นำเข้า nplusone.ext.sqlalchemy ด้วย profiler.profiler (): -
โดยค่าเริ่มต้น nplusone
จะบันทึกการสืบค้นที่ไม่จำเป็นทั้งหมดทั้งหมดโดยใช้เครื่องบันทึกชื่อ "NPlusone" เมื่อตั้งค่าตัวเลือกการกำหนดค่า NPLUSONE_RAISE nplusone
จะเพิ่ม NPlusOneError
สิ่งนี้สามารถใช้เพื่อบังคับการทดสอบอัตโนมัติทั้งหมดที่เกี่ยวข้องกับการสืบค้นที่ไม่จำเป็นเพื่อล้มเหลว
# django config nplusone_raise = true # flask config app.config ['nplusone_raise'] = true
สามารถระบุประเภทข้อยกเว้นได้หากต้องการโดยใช้ตัวเลือก NPLUSONE_ERROR
หากต้องการเพิกเฉยต่อการแจ้งเตือนจาก nplusone
ทั่วโลกให้กำหนดค่า Whitelist โดยใช้ตัวเลือก NPLUSONE_WHITELIST:
# django config nplusone_whitelist = [ {'label': 'n_plus_one', 'model': 'myapp.mymodel'} - # flask-sqlalchemy config app.config ['nplusone_whitelist'] = [ {'label': 'unused_eager_load', 'model': 'mymodel', 'ฟิลด์': 'my_field'} -
คุณสามารถอนุญาตโมเดล Whitelist ด้วยชื่อที่แน่นอนหรือตามรูปแบบ fnmatch:
# django config nplusone_whitelist = [ {'model': 'MyApp.*'} -
ในการระงับการแจ้งเตือนในพื้นที่ให้ใช้ตัวจัดการบริบท ignore
:
จาก nplusone.core นำเข้าสัญญาณ ด้วย signals.ignore (signals.lazy_load): # แถวขี้เกียจ -
MIT ได้รับใบอนุญาต ดูไฟล์ลิขสิทธิ์ที่มาพร้อมสำหรับรายละเอียดเพิ่มเติม