2013-10-01 16 views
9

Tôi đã đọc flask-sqlalchemy or sqlalchemy khuyến cáo sử dụng bình phương vuông với bình. Tôi muốn làm theo cách tiếp cận này.Làm thế nào để sử dụng bình phương sqlalchemy với mô hình sqlalchemy hiện tại?

Tuy nhiên, tôi có một mô hình hiện bằng văn bản cho các kịch bản dòng lệnh mà là dựa trên declarative_base SQLAlchemy của, ví dụ,

from sqlalchemy.ext.declarative import declarative_base 
Base = declarative_base() # create sqlalchemy Base class 
       : 
class Runner(Base): 
    etc. 

Tôi muốn vẫn có thể sử dụng các kịch bản dòng lệnh với mô hình này, mà còn muốn xây dựng một ứng dụng web xung quanh mô hình.

Có cách nào để mở rộng mô hình hiện tại, để đạt được lợi ích của việc sử dụng phần mở rộng bình phương sqlalchemy không? Hay tôi chỉ nên cuộn của riêng mình, và sử dụng ScopedSession của sqlalchemy?

+0

nó sẽ là một vấn đề để viết lại các kịch bản dòng lệnh bằng cách sử dụng mô hình bình phương sqlalchemy? –

+0

Tôi không biết - đã không sử dụng bình trước, hoặc giả kim bình và không biết tác dụng phụ. Các tập lệnh có cần phải được viết lại hay chỉ là mô hình được nhập khẩu? Tôi cũng nên đề cập rằng tôi đã sử dụng alembic để theo dõi các thay đổi của cơ sở dữ liệu, trong trường hợp có bất kỳ vấn đề tương thích nào ở đó. –

Trả lời

9

Hiện tại, đây là thứ không được hỗ trợ tốt nhưng không thể làm được. Xem this issue trong danh sách vấn đề Flask-SQLAlchemy, trong đó thừa nhận rằng việc thực hiện các phần mở rộng hiện tại làm cho tình trạng này đau đầu hơn họ nghĩ. Hy vọng rằng điều này sẽ được hỗ trợ tốt hơn trong tương lai (một khi một con đường di trú vững chắc và API mới được xác định).

vấn đề đó cho mẫu mã sau đây:

from flask import Flask 
from models import Base, User # Your non-Flask-SQLAlchemy models... 
from flask_sqlalchemy import SQLAlchemy 

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

@app.before_first_request 
def setup(): 
    # Recreate database each time for demo 
    Base.metadata.drop_all(bind=db.engine) 
    Base.metadata.create_all(bind=db.engine) 
    db.session.add(User('Bob Jones', '[email protected]')) 
    db.session.add(User('Joe Quimby', '[email protected]')) 
    db.session.commit() 

@app.route('/') 
def root(): 
    users = db.session.query(User).all() 
    return u"<br>".join([u"{0}: {1}".format(user.name, user.email) for user in users]) 

if __name__ == '__main__': 
    app.run('127.0.0.1', 5000) 

Có một vài điều cần lưu ý ở đây:

Trước tiên, bạn mất khả năng làm User.query (vì tài khoản được tạo bằng tường thuật riêng của mình cơ sở), cùng với tất cả những thứ khác mà Flask-SQLAlchemy's db.Model cung cấp cho bạn (chẳng hạn như khả năng tự động tạo tên bảng và các phương thức như first_or_404()).

Thứ hai, bất cứ khi nào bạn cần làm những việc liên quan đến siêu dữ liệu (chẳng hạn như drop_all hoặc create_all), bạn không thể sử dụng các phương pháp Flask-SQLAlchemy. Bạn phải sử dụng siêu dữ liệu gốc, liên kết với công cụ Flask-SQLAlchemy.

Tôi chưa thử điều này, vì vậy tôi không chắc liệu có bất kỳ gotchas nào khác trong cách tiếp cận này hay không. Bạn có thể muốn tham gia vào vé đó nếu bạn tìm thấy bất kỳ vé nào.

+0

Cảm ơn con trỏ tới vấn đề. Tôi có thể làm thí nghiệm, nhưng chắc chắn dễ dàng hơn nếu bạn biết câu trả lời này: Nếu tôi viết lại mô hình bằng cách sử dụng db.model của giả kim thuật, thay vì Base, với việc ngắt dòng lệnh? –

+0

@Lou_K: Có lẽ không phải là "phá vỡ" mỗi lần, nhưng khi bạn cố gắng chạy chúng, bạn có thể phải thực hiện thêm một số công việc thiết lập Flask App trước khi thịt của tập lệnh có thể chạy. –

+0

@Mark_Hildreth: Tôi có thể thử điều đó. Nếu điều đó trở nên nguy hiểm, có lẽ tôi có thể làm cho cùng một tệp nguồn hoạt động cho mô hình, nhưng phụ thuộc vào một số thông tin môi trường (một số loại cấu hình bên ngoài vào python, được đặt bởi dòng lệnh hoặc bởi ứng dụng web) để nhập đúng nội dung, và khai báo Base một cách thích hợp tùy thuộc vào việc nó được sử dụng bởi kịch bản dòng lệnh hay ứng dụng bình. Mặc dù vậy, không cảm thấy rất thanh lịch. Và điều này cần phải được suy nghĩ cẩn thận để đảm bảo hai hệ thống không va chạm với nhau bằng cách nào đó. –

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