flask-sqlalchemy หรือ sqlalchemy


95

ฉันใหม่ทั้งในขวดและ sqlalchemy ฉันเพิ่งเริ่มทำงานกับแอพขวดและตอนนี้ฉันใช้ sqlalchemy ฉันสงสัยว่ามีประโยชน์อย่างมากที่ฉันจะได้รับจากการใช้ flask-sqlalchemy กับ sqlalchemy หรือไม่ ฉันไม่พบแรงจูงใจที่เพียงพอในhttp://packages.python.org/Flask-SQLAlchemy/index.htmlหรือบางทีฉันอาจไม่เข้าใจค่า !! ฉันขอขอบคุณสำหรับคำชี้แจงของคุณ


6
อืมยังไม่มีคำตอบที่น่าพอใจที่นี่ ทุกคนสามารถอธิบายสิ่งที่เป็นผลประโยชน์ที่เป็นรูปธรรมที่แท้จริงของการflask-sqlalchemyมีความเก่าแก่กว่าธรรมดาsqlalchemyในแอปพลิเคขวด?
Steve Bennett

ข้อเสียใหญ่ประการหนึ่งคือFlask-SqlAlchemyไม่มีวิธีใด ๆ ในการตั้งค่าผู้เช่าหลายคนในแอป นั่นคือ IMO เชิงลบที่ใหญ่ที่สุด bindsมีให้เท่านั้นคือการแนบฐานข้อมูลที่แตกต่างกันไปยังรุ่นที่แตกต่างกันในขณะที่ไม่มีวิธีการใช้ฐานข้อมูลเฉพาะผู้เช่ากับรุ่นเดียวกัน
Rohit Jain

คำตอบ:


70

คุณสมบัติหลักของFlask-SQLAlchemyแอพพลิเคชั่นนี้คือการทำงานร่วมกับแอพพลิเคชั่น Flask อย่างเหมาะสม - มันสร้างและกำหนดค่าเอ็นจิ้นการเชื่อมต่อและเซสชันและกำหนดค่าให้ทำงานกับแอพ Flask

การตั้งค่านี้ค่อนข้างซับซ้อนเนื่องจากเราจำเป็นต้องสร้างเซสชันที่กำหนดขอบเขตและจัดการอย่างเหมาะสมตามวงจรชีวิตคำขอ / การตอบสนองของแอปพลิเคชัน Flask

ในโลกแห่งอุดมคติที่จะเป็นเพียงสิ่งเดียวFlask-SQLAlchemyแต่จริงๆแล้วมันเพิ่มอีกสองสามอย่าง นี่คือบล็อกโพสต์ที่ดีกับภาพรวมของสิ่งเหล่านั้นเข้าใจอย่างลึกซึ้งขวด-SQLAlchemy

เมื่อฉันทำงานกับ Flask และ SQLAlchemy ครั้งแรกฉันไม่ชอบค่าใช้จ่ายนี้ ฉันไปและแยกรหัสการจัดการเซสชันจากส่วนขยาย วิธีนี้ใช้ได้ผลแม้ว่าฉันจะพบว่ามันค่อนข้างยากที่จะทำการผสานรวมนี้อย่างถูกต้อง

ดังนั้นแนวทางที่ง่ายกว่า (ซึ่งใช้ในโปรเจ็กต์อื่นที่ฉันกำลังทำอยู่) คือเพียงแค่ปล่อยเข้าFlask-SQLAlchemyและอย่าใช้คุณสมบัติเพิ่มเติมใด ๆ ที่มีให้ คุณจะมีdb.sessionและใช้งานได้ราวกับว่าเป็นการSQLAlchemyตั้งค่าที่แท้จริง


4
ฉันยังคงสับสน บล็อกโพสต์ที่เชื่อมโยง (และเอกสารอย่างเป็นทางการ!) จะแสดงรายการคุณลักษณะ SQLAlchemy ธรรมดา (เช่นฐานที่เปิดเผย) ราวกับว่าเป็นคุณสมบัติของ Flask-SQLAlchemy ไม่ชัดเจนว่าพวกเขารับเครดิตสำหรับสิ่งที่สร้างไว้ใน SQLAlchemy หรือพวกเขานำมาใช้ใหม่ (หรือทำไมพวกเขาถึงทำเช่นนั้นหากเป็นอย่างหลัง) ย่อหน้าแรกของคุณแสดงคุณสมบัติสองประการ ได้แก่ ตัวปิดความสะดวกสำหรับการจัดการเซสชัน (แต่คุณไม่จำเป็นต้องม้วนเองอีกต่อไปหากคุณต้องการใช้โมเดล SQLAlchemy นอก Flask?) และ "การกำหนดค่า" ที่ไม่ระบุบางส่วนเพื่อ"ทำงานกับแอป Flask" . นั่นหมายความว่าอย่างไร?
Mark Amery

1
ฉันยังสับสนเล็กน้อยกับคำถาม โพสต์บล็อกที่เชื่อมโยงเป็น IMO ที่ค่อนข้างชัดเจนเช่นมีข้อความว่า "Custom Declarative model with support for query property and pagination" คีย์คือ "กำหนดเอง" และ "พร้อมการสนับสนุนคุณสมบัติเคียวรีและการแบ่งหน้า" คือสิ่งที่เพิ่มไว้ด้านบนของ ฐานประกาศของ SQLAlchemy
Boris Serebrov

1
เกี่ยวกับ "เครื่องห่อความสะดวก" - ไม่ได้มีไว้เพื่อความสะดวก แต่เพื่อให้สิ่งต่างๆทำงานได้อย่างถูกต้อง ในการเริ่มใช้ SQLAlchemy คุณต้องมีอ็อบเจ็กต์การเชื่อมต่อฐานข้อมูล (eninge / connection / session) และคุณไม่ต้องการสร้างสิ่งเหล่านี้ทุกครั้งที่คุณต้องสร้างแบบสอบถาม SQL ดังนั้นสิ่งเหล่านี้ควรถูกสร้างขึ้นทั่วโลกและสามารถใช้ได้กับโค้ดแอปพลิเคชัน ดังนั้นคุณสามารถทำบางอย่างเช่น "from yourapplication import db" จากนั้นทำ "db.session.something ()" โดยไม่ต้องคิดว่าจะสร้างและเริ่มต้นอ็อบเจ็กต์ "db" นี้ได้อย่างไร
Boris Serebrov

และเกี่ยวกับ "การกำหนดค่า" ที่ไม่ระบุถึง "ทำงานกับแอป Flask" มีระบุไว้ในย่อหน้าที่สอง: This setup is quite complex as we need to create the scoped session and properly handle it according to the Flask application request/response life-cycle.ดูรายละเอียดเพิ่มเติมในเอกสาร SQLAlchemy: ฉันจะสร้างเซสชันเมื่อใดฉันจะยอมรับเมื่อใดและฉันควรทำเมื่อใด ปิดมัน? และบริบท / เซสชันกระทู้ท้องถิ่น
Boris Serebrov

22

Flask-SQLAlchemy ช่วยให้คุณมีสิ่งพิเศษมากมายที่คุณจะต้องใช้งานด้วยตัวเองโดยใช้ SQLAlchemy

ด้านบวกในการใช้ Flask-SQLAlchemy


  1. Flask_SQLAlchemy จัดการการกำหนดค่าเซสชันการตั้งค่าและการฉีกขาดให้คุณ
  2. ให้รูปแบบพื้นฐานที่เปิดเผยซึ่งทำให้การสืบค้นและการแบ่งหน้าง่ายขึ้น
  3. การตั้งค่าเฉพาะแบ็กเอนด์ Flask-SQLAlchemy สแกน libs ที่ติดตั้งเพื่อรองรับ Unicode และหากล้มเหลวโดยอัตโนมัติให้ใช้ SQLAlchemy Unicode
  4. มีวิธีการที่เรียกapply_driver_hacksว่าตั้งค่าเริ่มต้นที่มีเหตุผลเป็น thigs โดยอัตโนมัติเช่น MySQL pool-size
  5. มีวิธีการสร้างที่ดีใน create_all () และ drop_all () สำหรับการสร้างและวางตารางทั้งหมด มีประโยชน์สำหรับการทดสอบและใน python command line หากคุณทำอะไรโง่ ๆ
  6. ให้ get_or_404 () แทน get () และ find_or_404 () แทน find () Code ตัวอย่างที่> http://flask-sqlalchemy.pocoo.org/2.1/queries/

ตั้งชื่อตารางโดยอัตโนมัติ Flask-SQLAlchemy ตั้งค่าชื่อตารางของคุณโดยอัตโนมัติโดยการแปลงClassName> class_nameสิ่งนี้สามารถแทนที่ได้โดยการตั้งค่า__tablename__รายการคลาส

ด้านลบในการใช้ Flask-SQLAlchemy


  1. การใช้ Flask-SQLAlchemy จะเพิ่มปัญหาในการย้ายข้อมูลจาก Flask ให้สมมติว่า Pyramid ถ้าคุณต้องการ สาเหตุหลักมาจากรูปแบบฐานที่ประกาศกำหนดเองบน Flask_SQLAchemy
  2. การใช้ Flask-SQLAlchemy คุณเสี่ยงที่จะใช้แพ็คเกจที่มีชุมชนขนาดเล็กกว่า SQLAlchemy ซึ่งฉันไม่สามารถละจากการพัฒนาที่ใช้งานได้ในเร็ว ๆ นี้
  3. Flask-SQLAlchemy พิเศษที่ดีบางอย่างอาจทำให้คุณสับสนได้หากคุณไม่รู้ว่ามีอยู่ที่นั่น

21

บอกตามตรงว่าไม่เห็นประโยชน์อะไร IMHO, Flask-SQLAlchemy สร้างเลเยอร์เพิ่มเติมที่คุณไม่ต้องการจริงๆ ในกรณีของเราเรามีแอปพลิเคชัน Flask ที่ค่อนข้างซับซ้อนซึ่งมีฐานข้อมูล / การเชื่อมต่อหลายแบบ (master-slave) โดยใช้ทั้ง ORM และ Core โดยที่เราจำเป็นต้องควบคุมเซสชัน / ธุรกรรม DB ของเรา (เช่นโหมด dryrun vs คอมมิต) Flask-SQLAlchemy เพิ่มฟังก์ชันเพิ่มเติมบางอย่างเช่นการทำลายเซสชันโดยอัตโนมัติโดยสมมติว่ามีบางอย่างสำหรับคุณซึ่งมักไม่ใช่สิ่งที่คุณต้องการ


6
ใช่ในกรณีการใช้งานของคุณดูเหมือนว่า Flask-SQLAlchemy ล้าสมัย แต่ถ้า OP มีสถานการณ์เช่นนี้เขาคงไม่ถามคำถามนี้ สำหรับผู้ใช้ใหม่ที่ไม่รู้อะไรเกี่ยวกับขอบเขตเซสชัน Flask-SQLAlchemy แน่นอนว่าต้อง!
schlamar

16

เอกสาร SQLAlchemy ระบุอย่างชัดเจนว่าคุณควรใช้ Flask-SQLAlchemy (โดยเฉพาะอย่างยิ่งหากคุณไม่เข้าใจประโยชน์ของมัน!):

[... ] ผลิตภัณฑ์เช่น Flask-SQLAlchemy [... ] SQLAlchemy ขอแนะนำให้ใช้ผลิตภัณฑ์เหล่านี้ตามที่มีอยู่

คำพูดนี้และแรงจูงใจที่มีรายละเอียดที่คุณจะพบในคำถามที่สองของเซสชันคำถามที่พบบ่อย


2
Flask-sqlalchemy ดูเหมือนจะไม่ได้รับการดูแล การอัปเดตล่าสุดคือเมื่อวันที่ 1 สิงหาคม 2013 คำแนะนำนี้เกี่ยวข้องอีกหรือไม่
pmav99

@ pmav99 ตราบเท่าที่คุณไม่มีปัญหาที่เป็นรูปธรรมฉันยังคงแนะนำโดยเฉพาะสำหรับผู้ใช้ใหม่
schlamar

1
ดูเหมือนว่าจะได้รับการดูแลอย่างแข็งขันในเดือนพฤศจิกายน 2014 การกระทำล่าสุดจำนวนมาก github.com/mitsuhiko/flask-sqlalchemy/commits/master
Steve Bennett

26
ถึงแม้ OP ไม่ได้ถามมันโดยตรง imo. เขาต้องการทราบถึงประโยชน์ของ Flask-SQLAlchemy คำตอบของคุณคือ "ใช้แม้ว่าคุณจะไม่รู้ว่ามีประโยชน์อะไร" - ใช่ประโยชน์คืออะไร?
Markus Meskanen

1
คำตอบนี้ไม่ตอบคำถามของ OP คุณกำลังแนะนำ flask-sqlalchemy โดยไม่ต้องให้เหตุผลมากนักที่อยู่เบื้องหลังคำแนะนำ
mbadawi23

7

ตามที่ @schlamar แนะนำ Flask-SqlAlchemy เป็นสิ่งที่ดี Id แค่ต้องการเพิ่มบริบทพิเศษบางอย่างให้กับประเด็นที่เกิดขึ้นที่นั่น

อย่ารู้สึกว่าคุณกำลังเลือกอย่างใดอย่างหนึ่ง ตัวอย่างเช่นสมมติว่าเราต้องการดึงข้อมูลทั้งหมดจากตารางโดยใช้แบบจำลองโดยใช้ Flask-Sqlalchemy มันง่ายเหมือน

Model.query.all()

สำหรับกรณีง่ายๆหลายอย่าง Flask-Sqlalchemy จะไม่เป็นไร จุดพิเศษที่ฉันอยากจะทำคือถ้า Flask-Sqlalchemy ไม่ทำในสิ่งที่คุณต้องการก็ไม่มีเหตุผลที่คุณจะไม่สามารถใช้ SqlAlchemy ได้โดยตรง

from myapp.database import db

num_foo = db.session.query(func.count(OtherModel.id)).filter(is_deleted=False).as_scalar()

db.session.query(Model.id, num_foo.label('num_foo')).order_by('num_foo').all()

อย่างที่คุณเห็นเราสามารถข้ามจากที่หนึ่งไปยังอีกที่หนึ่งได้อย่างง่ายดายโดยไม่มีปัญหาและในตัวอย่างที่สองเราใช้โมเดลที่กำหนดของ Flask-Sqlalchemy


1
"ตัวอย่างเช่นสมมติว่าเราต้องการที่จะคว้าระเบียนทั้งหมดจากตารางการใช้รูปแบบการใช้ขวด-sqlalchemy มันเป็นง่ายๆเป็น. Model.query.all()" - ทั้งหมดนี้สามารถทำได้ด้วยเพียง SQLAlchemy ใช้ขวด-SQLAlchemy ให้แน่นอนไม่มีอะไรใหม่ที่นี่
Markus Meskanen

คุณสุดยอดมาก! ฉันสะดุดกับโพสต์นี้และมันช่วยแก้ปัญหาที่ฉันมีได้ หลังจากที่ฉันติดตั้ง anaconda ด้วยเหตุผลบางประการการอัปเดตตามปกติไม่ทำงาน เปลี่ยนจากModel.query.all()เป็นdb.session.query(Model).all()ด้วยเหตุผลบางประการทำให้เซสชันติดตามและอัปเดตได้ตามปกติ
Jeff Bluemel

2

นี่คือตัวอย่างของประโยชน์ของขวด - sqlalchemy ให้คุณมากกว่า sqlalchemy ธรรมดา

สมมติว่าคุณกำลังใช้ flask_user

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

class MyAdapter(DBAdapter):
    def get_object(self, ObjectClass, id):
        """ Retrieve one object specified by the primary key 'pk' """
        pass

    def find_all_objects(self, ObjectClass, **kwargs):
         """ Retrieve all objects matching the case sensitive filters in 'kwargs'. """
        pass


    def find_first_object(self, ObjectClass, **kwargs):
        """ Retrieve the first object matching the case sensitive filters in 'kwargs'. """
        pass

    def ifind_first_object(self, ObjectClass, **kwargs):
        """ Retrieve the first object matching the case insensitive filters in 'kwargs'. """
        pass

    def add_object(self, ObjectClass, **kwargs):
        """ Add an object of class 'ObjectClass' with fields and values specified in '**kwargs'. """
        pass

    def update_object(self, object, **kwargs):
        """ Update object 'object' with the fields and values specified in '**kwargs'. """
        pass

    def delete_object(self, object):
        """ Delete object 'object'. """
        pass

    def commit(self):
        pass

หากคุณใช้ flask-sqlalchemy คุณสามารถใช้ SQLAlchemyAdapter ในตัว หากคุณใช้ sqlalchemy (ไม่ใช่ขวด - sqlalchemy) คุณอาจตั้งสมมติฐานที่แตกต่างกันเกี่ยวกับวิธีการบันทึกวัตถุลงในฐานข้อมูล (เช่นชื่อของตาราง) ดังนั้นคุณจะต้องเขียนคลาสอะแดปเตอร์ของคุณเอง

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.