flask-sqlalchemy hoặc sqlalchemy


93

Tôi mới sử dụng cả flask và sqlalchemy, tôi mới bắt đầu làm việc trên một ứng dụng flask và hiện tại tôi đang sử dụng sqlalchemy. Tôi đã tự hỏi liệu tôi có thể nhận được lợi ích đáng kể nào khi sử dụng flask-sqlalchemy vs sqlalchemy hay không. Tôi không thể tìm thấy đủ động lực trong http://packages.python.org/Flask-SQLAlchemy/index.html hoặc có thể tôi không hiểu giá trị !! Tôi sẽ đánh giá cao sự làm rõ của bạn.


6
Hmm, vẫn chưa có câu trả lời thỏa đáng ở đây. Bất cứ ai có thể giải thích những lợi ích cụ thể thực sự của ứng dụng Flask đã flask-sqlalchemyquá cũ kỹ sqlalchemylà gì không?
Steve Bennett

Tuy nhiên, Flask-SqlAlchemycó một nhược điểm lớn là không cung cấp bất kỳ cách nào để thiết lập nhiều hình thức thuê nhà trong ứng dụng. Đó là tiêu cực lớn nhất của IMO. bindschỉ được cung cấp là đính kèm cơ sở dữ liệu khác nhau vào mô hình khác nhau, trong khi không có cách nào để sử dụng cơ sở dữ liệu dành riêng cho người thuê với cùng một mô hình.
Rohit Jain

Câu trả lời:


67

Tính năng chính của Flask-SQLAlchemynó là tích hợp thích hợp với ứng dụng Flask - nó tạo và cấu hình engine, kết nối và phiên và cấu hình nó để hoạt động với ứng dụng Flask.

Thiết lập này khá phức tạp vì chúng ta cần tạo phiên theo phạm vi và xử lý đúng cách theo vòng đời yêu cầu / phản hồi của ứng dụng Flask.

Trong thế giới lý tưởng đó sẽ là đặc điểm duy nhất của nó Flask-SQLAlchemy, nhưng thực ra nó còn bổ sung thêm vài thứ nữa. Đây là một bài đăng blog hay với tổng quan về chúng: Làm sáng tỏ Flask-SQLAlchemy .

Khi tôi lần đầu tiên làm việc với Flask và SQLAlchemy, tôi không thích điều này. Tôi đã xem qua và trích xuất mã quản lý phiên từ tiện ích mở rộng. Cách tiếp cận này hoạt động, mặc dù tôi phát hiện ra rằng khá khó để thực hiện tích hợp này đúng cách.

Vì vậy, cách tiếp cận dễ dàng hơn (được sử dụng trong một dự án khác mà tôi đang làm việc) là chỉ cần đăng Flask-SQLAlchemynhập và không sử dụng bất kỳ tính năng bổ sung nào mà nó cung cấp. Bạn sẽ có db.sessionvà có thể sử dụng nó như thể nó được SQLAlchemythiết lập thuần túy .


4
Tôi vẫn còn bối rối. Bài đăng trên blog được liên kết (và các tài liệu chính thức!) Liệt kê một số tính năng SQLAlchemy thuần túy (như cơ sở khai báo) như thể chúng là các tính năng của Flask-SQLAlchemy; không rõ liệu họ có ghi công cho những thứ được tích hợp trong SQLAlchemy hay họ đã hoàn thiện lại nó (cũng như lý do tại sao họ làm như vậy, nếu đó là thứ sau). Đoạn đầu tiên của bạn liệt kê hai tính năng: trình bao bọc tiện lợi để quản lý phiên (nhưng bạn sẽ không cần phải tự cuộn nếu muốn sử dụng các mô hình SQLAlchemy của mình bên ngoài Flask?) Và một số "cấu hình" không xác định để "hoạt động với ứng dụng Flask" . Điều đó có nghĩa là gì?
Mark Amery

1
Tôi cũng hơi bối rối trước những câu hỏi. Bài đăng trên blog được liên kết có IMO khá rõ ràng, ví dụ: nó nói "Mô hình cơ sở khai báo tùy chỉnh với hỗ trợ thuộc tính truy vấn và phân trang", khóa là "tùy chỉnh" và "với hỗ trợ thuộc tính truy vấn và phân trang" là những gì nó thêm vào đầu Cơ sở khai báo của SQLAlchemy.
Boris Serebrov

1
Về "trình bao bọc tiện lợi" - chúng không phải để tạo sự tiện lợi mà là để làm cho mọi thứ hoạt động bình thường. Để bắt đầu sử dụng SQLAlchemy, bạn cần các đối tượng kết nối cơ sở dữ liệu (eninge / connection / session) và bạn không muốn tạo các đối tượng này mỗi khi bạn cần thực hiện truy vấn SQL, vì vậy chúng phải được tạo trên toàn cầu và có sẵn trên mã ứng dụng. Vì vậy, bạn có thể làm điều gì đó như "from yourapplication import db" và sau đó thực hiện "db.session.something ()" mà không cần suy nghĩ cách tạo và khởi tạo đối tượng "db" này đúng cách.
Boris Serebrov

Và liên quan đến "cấu hình" không xác định để "hoạt động với ứng dụng Flask" - nó thực sự được chỉ định trong đoạn thứ hai: 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.Xem thêm chi tiết trong tài liệu SQLAlchemy: Khi nào tôi tạo một Phiên, khi nào tôi cam kết nó và khi nào tôi đóng nó? Phiên theo ngữ cảnh / chuỗi cục bộ .
Boris Serebrov

20

Thành thật mà nói, tôi không thấy bất kỳ lợi ích nào. IMHO, Flask-SQLAlchemy tạo ra một lớp bổ sung mà bạn không thực sự cần. Trong trường hợp của chúng tôi, chúng tôi có một ứng dụng Flask khá phức tạp với nhiều cơ sở dữ liệu / kết nối (master-slave) sử dụng cả ORM và Core, trong đó, trong số những thứ khác, chúng tôi cần kiểm soát các phiên / giao dịch DB của mình (ví dụ như chế độ dryrun và cam kết). Flask-SQLAlchemy thêm một số chức năng bổ sung như tự động hủy phiên làm việc giả định một số thứ đối với bạn mà thường không phải là thứ bạn cần.


5
Có, trong trường hợp sử dụng của bạn, Flask-SQLAlchemy dường như đã lỗi thời. Nhưng nếu OP gặp một kịch bản như vậy thì có lẽ ông ấy sẽ không đặt câu hỏi này. Đối với một người dùng mới chưa biết gì về phạm vi phiên thì chắc chắn phải có Flask-SQLAlchemy!
schlamar

20

Flask-SQLAlchemy cung cấp cho bạn một số tính năng bổ sung tuyệt vời mà bạn có thể tự thực hiện bằng SQLAlchemy.

Mặt tích cực khi sử dụng Flask-SQLAlchemy


  1. Flask_SQLAlchemy xử lý cấu hình, thiết lập và chia nhỏ phiên cho bạn.
  2. Cung cấp cho bạn mô hình cơ sở khai báo giúp truy vấn và phân trang dễ dàng hơn
  3. Cài đặt cụ thể phụ trợ. Flask-SQLAlchemy quét các lib đã cài đặt để hỗ trợ Unicode và nếu không thành công sẽ tự động sử dụng SQLAlchemy Unicode.
  4. Có một phương thức được gọi là apply_driver_hackstự động đặt các giá trị mặc định lành mạnh cho các lỗi như MySQL pool-size
  5. Có bản dựng đẹp trong các phương thức create_all () và drop_all () để tạo và xóa tất cả các bảng. Hữu ích để thử nghiệm và trong dòng lệnh python nếu bạn đã làm điều gì đó ngu ngốc
  6. Nó cung cấp cho bạn get_or_404 () thay vì get () và find_or_404 () thay vì find () Ví dụ về mã tại> http://flask-sqlalchemy.pocoo.org/2.1/queries/

Tự động đặt tên bảng. Flask-SQLAlchemy tự động đặt tên bảng của bạn để chuyển đổi tên của bạn ClassName> class_nameđiều này có thể được ghi đè bằng cách đặt __tablename__mục Danh sách lớp

Mặt tiêu cực khi sử dụng Flask-SQLAlchemy


  1. Sử dụng Flask-SQLAlchemy sẽ gây thêm khó khăn cho việc di chuyển từ Flask, giả sử như Pyramid nếu bạn cần. Điều này chủ yếu là do mô hình cơ sở khai báo tùy chỉnh trên Flask_SQLAchemy.
  2. Sử dụng Flask-SQLAlchemy, bạn có nguy cơ sử dụng một gói có cộng đồng nhỏ hơn nhiều so với chính SQLAlchemy, điều mà tôi không thể dễ dàng loại bỏ khỏi quá trình phát triển tích cực bất cứ lúc nào.
  3. Một số tính năng bổ sung tuyệt vời mà Flask-SQLAlchemy có có thể khiến bạn bối rối nếu bạn không biết chúng ở đó.

15

Tài liệu SQLAlchemy nói rõ rằng bạn nên sử dụng Flask-SQLAlchemy (đặc biệt nếu bạn không hiểu lợi ích của nó!):

[...] các sản phẩm như Flask-SQLAlchemy [...] SQLAlchemy đặc biệt khuyến nghị rằng các sản phẩm này được sử dụng khi có sẵn.

Trích dẫn này và động lực chi tiết bạn có thể tìm thấy trong câu hỏi thứ hai của Câu hỏi thường gặp về phiên .


2
Flask-sqlalchemy dường như không có gì lạ. Lần cập nhật cuối cùng là vào ngày 1 tháng 8 năm 2013. Lời khuyên này còn phù hợp nữa không?
pmav99

@ pmav99 miễn là bạn không có vấn đề cụ thể với nó, tôi vẫn sẽ giới thiệu nó, đặc biệt là cho người dùng mới.
schlamar

1
Có vẻ như được duy trì tích cực kể từ tháng 11 năm 2014. Rất nhiều cam kết gần đây. github.com/mitsuhiko/flask-sqlalchemy/commits/master
Steve Bennett

25
Mặc dù OP không hỏi nó trực tiếp, imo. anh ấy muốn biết những lợi ích của Flask-SQLAlchemy. Câu trả lời của bạn theo nghĩa đen là "hãy sử dụng nó ngay cả khi bạn không biết lợi ích là gì" - vâng, lợi ích là gì?
Markus Meskanen

1
Câu trả lời này không trả lời câu hỏi của OP. Bạn đang đề xuất flask-sqlalchemy, mặc dù cung cấp nhiều lý do đằng sau đề xuất.
mbadawi23

7

như @schlamar gợi ý Flask-SqlAlchemy là một điều tốt. Tôi chỉ muốn thêm một số ngữ cảnh bổ sung vào điểm được thực hiện ở đó.

Đừng cảm thấy như bạn đang chọn cái này hơn cái kia. Ví dụ, giả sử chúng ta muốn lấy tất cả các bản ghi từ một bảng bằng mô hình sử dụng Flask-Sqlalchemy. Nó đơn giản như

Model.query.all()

Đối với nhiều trường hợp đơn giản, Flask-Sqlalchemy sẽ hoàn toàn ổn. Điểm bổ sung mà tôi muốn làm là, nếu Flask-Sqlalchemy không làm những gì bạn muốn thì không có lý do gì bạn không thể sử dụng SqlAlchemy trực tiếp.

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

Như bạn có thể thấy, chúng ta có thể dễ dàng chuyển từ cái này sang cái khác mà không gặp khó khăn gì và trong ví dụ thứ hai, trên thực tế, chúng tôi đang sử dụng các mô hình được xác định bởi Flask-Sqlalchemy.


1
"Ví dụ, giả sử chúng tôi muốn lấy tất cả các bản ghi từ một bảng bằng mô hình sử dụng Flask-Sqlalchemy. Nó đơn giản như Model.query.all()" - tất cả điều này có thể được thực hiện chỉ với SQLAlchemy, sử dụng Flask-SQLAlchemy hoàn toàn không cung cấp gì mới ở đây.
Markus Meskanen

bạn thật tuyệt vời! Tôi tình cờ xem được bài đăng này và nó đã giải quyết được một vấn đề mà tôi đang gặp phải. sau khi tôi cài đặt anaconda, vì một số lý do mà các bản cập nhật bình thường không hoạt động. đã thay đổi từ Model.query.all()thành db.session.query(Model).all()vì một số lý do đã cho phép các phiên theo dõi và cập nhật như bình thường.
Jeff Bluemel

2

Đây là một ví dụ về lợi ích mà flask-sqlalchemy mang lại cho bạn so với sqlalchemy đơn thuần.

Giả sử bạn đang sử dụng flask_user.

flask_user tự động tạo và xác thực các đối tượng người dùng, vì vậy nó cần truy cập vào cơ sở dữ liệu của bạn. Lớp UserManager thực hiện điều này bằng cách gọi thông qua một thứ gọi là "bộ điều hợp" để tóm tắt các lệnh gọi cơ sở dữ liệu. Bạn cung cấp bộ điều hợp trong hàm tạo UserManager và bộ điều hợp phải triển khai các chức năng sau:

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

Nếu bạn đang sử dụng flask-sqlalchemy, bạn có thể sử dụng SQLAlchemyAdapter tích hợp sẵn. Nếu bạn đang sử dụng sqlalchemy (not-flask-sqlalchemy), bạn có thể đưa ra các giả định khác nhau về cách các đối tượng được lưu vào cơ sở dữ liệu (như tên của các bảng), vì vậy bạn sẽ phải viết lớp bộ điều hợp của riêng mình.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.