2015-05-08 16 views
9

Tôi đã có một dịch vụ web nhỏ được xây dựng bằng cách sử dụng FlaskFlask-SQLAlchemy chỉ có một mô hình. Bây giờ tôi muốn sử dụng cùng một cơ sở dữ liệu, nhưng với một ứng dụng dòng lệnh, vì vậy tôi muốn giảm sự phụ thuộc Flask.Sử dụng Flask-SQLAlchemy không có Flask

Mô hình của tôi trông như thế này:

class IPEntry(db.Model): 
    id = db.Column(db.Integer, primary_key=True) 
    ip_address = db.Column(db.String(16), unique=True) 
    first_seen = db.Column(db.DateTime(), 
     default = datetime.datetime.utcnow 
    ) 
    last_seen = db.Column(db.DateTime(), 
     default = datetime.datetime.utcnow 
    ) 

    @validates('ip') 
    def validate_ip(self, key, ip): 
     assert is_ip_addr(ip) 
     return ip 

Kể từ db sẽ không còn là một tham chiếu đến flask.ext.sqlalchemy.SQLAlchemy(app), làm thế nào tôi có thể chuyển đổi mô hình của tôi sử dụng chỉ SQLAlchemy. Có cách nào cho hai ứng dụng (một với Flask-SQLAlchemy mục kia có SQLAlchemy) để sử dụng cùng một cơ sở dữ liệu không?

+0

Các * cơ sở dữ liệu * nên không phụ thuộc vào * mô hình * hoặc lớp ORM bạn đang sử dụng. – Makoto

+0

Vâng, tôi hiểu rồi. Tôi đang tìm một cách để tái sử dụng mã trong cả bình và bình mà không cần phải thay đổi định nghĩa mô hình của tôi theo bất kỳ cách nào đáng kể. – amccormack

+0

Không có gì liên quan đến bình trong mô hình của bạn. Tất cả những gì bạn cần là tạo một kết nối db và nhập mô hình của bạn vào một trong hai bình, hoặc ứng dụng không bình. Tôi chỉ đơn giản là đặt mô hình trong 'models.py' như vậy (thực sự chỉ cần di chuyển ở trên từ tập tin .py chính và nhập/khởi tạo IPentry khi cần thiết). –

Trả lời

0

Kiểm tra này một github.com/mardix/active-alchemy

Active-Alchemy là một trình bao bọc giả thuyết về khung công tác cho SQLAlchemy, giúp cho việc sử dụng này trở nên dễ sử dụng bằng cách triển khai một bản ghi hoạt động đơn giản như api, trong khi nó vẫn sử dụng db.session bên dưới. Lấy cảm hứng từ Flask-SQLAlchemy

0

bạn có thể làm điều này để thay thế db.Model:

from sqlalchemy import orm 
from sqlalchemy.ext.declarative import declarative_base 
import sqlalchemy as sa 

base = declarative_base() 
engine = sa.create_engine(YOUR_DB_URI) 
base.metadata.bind = engine 
session = orm.scoped_session(orm.sessionmaker())(bind=engine) 

# after this: 
# base == db.Model 
# session == db.session 
# other db.* values are in sa.* 
# ie: old: db.Column(db.Integer,db.ForeignKey('s.id')) 
#  new: sa.Column(sa.Integer,sa.ForeignKey('s.id')) 
# except relationship, and backref, those are in orm 
# ie: orm.relationship, orm.backref 
# so to define a simple model 

class UserModel(base): 
    __tablename__ = 'users' #<- must declare name for db table 
    id = sa.Column(sa.Integer,primary_key=True) 
    name = sa.Column(sa.String(255),nullable=False) 

sau đó để tạo ra các bảng:

base.metadata.create_all() 
1

này không hoàn toàn trả lời câu hỏi của bạn, bởi vì nó không xóa phụ thuộc Flask, nhưng bạn có thể sử dụng SqlAlchemy trong tập lệnh và kiểm tra chỉ bằng không chạy ứng dụng Flask.

from flask import Flask 
from flask_sqlalchemy import SQLAlchemy 
from sqlalchemy import MetaData 

test_app = Flask('test_app') 
test_app.config['SQLALCHEMY_DATABASE_URI'] = 'database_uri' 
test_app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False 

metadata = MetaData(schema='myschema') 
db = SQLAlchemy(test_app, metadata=metadata) 

class IPEntry(db.Model): 
    pass 

Một khó khăn mà bạn có thể gặp phải là yêu cầu của việc sử dụng db.Model như một lớp cơ sở cho mô hình của bạn nếu bạn muốn nhắm đến các ứng dụng web và các kịch bản độc lập sử dụng cùng một codebase. Cách có thể để giải quyết nó là sử dụng đa hình động và bọc định nghĩa lớp trong một hàm.

def get_ipentry(db): 
    class IPEntry(db.Model): 
     pass 
    return IPEntry 

Khi bạn xây dựng thời gian chạy lớp trong hàm, bạn có thể chuyển vào các trường hợp SqlAlchemy khác nhau. Nhược điểm duy nhất là bạn cần phải gọi hàm để xây dựng lớp trước khi sử dụng nó.

db = SqlAlchemy(...) 
IpEntry = get_ipentry(db) 
IpEntry.query.filter_by(id=123).one() 
Các vấn đề liên quan