2011-04-25 35 views
5

Cho phép nói rằng tôi có một phần của ứng dụng Flask của tôi mà tôi muốn kéo ra và sử dụng trong nhiều dự án khác nhau. Nó có các mô hình SQLAlchemy sử dụng Flask-SQLAlchemy, cũng như các khung nhìn và các khuôn mẫu. Tôi có thể nhận được app.route trang trí bằng cách sử dụng một mô-đun, nhưng làm thế nào tôi có thể xử lý đối tượng db SQLAlchemy?Làm cách nào để bạn tạo thành phần có thể sử dụng lại với Flask-SQLAlchemy?

Vì thành phần của tôi cần tách biệt, tôi không thể chỉ nhập đối tượng db. Nhưng tôi không nghĩ rằng tôi nên tạo đối tượng db hai lần. Làm cách nào để kết hợp siêu dữ liệu với siêu dữ liệu trong phần còn lại của dự án?

Trả lời

3

Lúc đầu, bạn phải chia sẻ metadata và không sử dụng bình phương-sqlalchemy db.Model làm cơ sở cho bạn có thể sử dụng lại ứng dụng.

Thứ hai, bạn phải tạo lại tất cả các lớp với việc mở rộng cơ sở mới từ bình phương sqlalchemy cho tín hiệu hỗ trợ, cắt ngắn và các thứ khác.

Tích hợp các căn cứ (nó có thể là lỗi):

def integrate_models(cls, nbase): 
     new_bases = list(cls.__bases__) + [nbase] 
     new_dict = dict(cls.__dict__) 
     new_dict.update(dict(nbase.__dict__)) 
     return type.__new__(cls.__class__, cls.__name__, tuple(new_bases), new_dict) 
ứng dụng

Ví dụ Flask với phần mở rộng SQLAlchemy:

# -*- coding: utf-8 -*- 
from flask import Flask 
from flaskext.sqlalchemy import SQLAlchemy 

app = Flask(__name__) 
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////tmp/test.db' 
db = SQLAlchemy(app) 

class User(db.Model): 
    id = db.Column(db.Integer, primary_key=True) 
    username = db.Column(db.String(80), unique=True) 
    email = db.Column(db.String(120), unique=True) 

    def __init__(self, username, email): 
     self.username = username 
     self.email = email 

    def __repr__(self): 
     return '<User %r>' % self.username 

if __name__ == '__main__': 
     from some_model_base import init_metadata 
     init_metadata(db.Model.metadata) 

     from some_model import SomeClass 

     SomeClass = integrate_models(SomeClass, db.Model) 

     db.create_all() 

     print SomeClass.query.all() 

đâu some_model_base.py:

from sqlalchemy.ext.declarative import declarative_base 
Base = declarative_base() 

def init_metadata(metadata): 
    Base.metadata = metadata 

Và some_model.py :

from sqlalchemy import Column, Integer, String 
from some_model_base import Base 

class SomeClass(Base): 
    __tablename__ = 'some_table' 
    id = Column(Integer, primary_key=True) 
    name = Column(String(50)) 

Trong ví dụ này chỉ kiểm tra lối tắt db.create_all và SomeClass.query.

Xin lỗi vì tiếng Anh kém của tôi.

+0

Hm, tôi sẽ cần dùng thử. Bạn có thể tìm cách cấu hình các mô hình trong mô-đun kia để có mối quan hệ với các mô hình trong chương trình chính không? –

+0

Tôi nghĩ rằng cách tốt nhất làm điều đó - khai báo trong các lớp cơ sở ứng dụng có thể tái sử dụng của bạn hoặc MixIns và sau đó xây dựng các mô hình cụ thể phân lớp chúng. – estin

1

Bạn nên sử dụng flask.current_app, nó là đối tượng proxy để truy cập vào ứng dụng hiện tại và đó là những gì được sử dụng trong một số tiện ích mở rộng. Vì vậy, mã của bạn sẽ trông giống như sau:

from flask import current_app 
from flaskext.sqlalchemy import SQLAlchemy 

db = SQLAlchemy(current_app) 

và sau đó sử dụng đối tượng db như bạn thường làm. Nhưng tôi không chắc chắn nếu điều này sẽ làm việc nếu người dùng sử dụng mô-đun của bạn và cũng cần thiết để sử dụng flaskext.sqlalchemy, có thể nó sẽ xung đột, tôi đề nghị để kiểm tra này, để chắc chắn mô-đun của bạn sẽ được 100% tương thích với bất kỳ ứng dụng flask .

Các vấn đề liên quan