2011-04-25 32 views
5

Powiedzmy, że mam część mojej aplikacji Flask, którą chcę wyciągnąć i użyć w wielu różnych projektach. Ma modele SQLAlchemy z wykorzystaniem Flask-SQLAlchemy, a także widoki i szablony. Mogę uzyskać dekoratory app.route przy użyciu modułu, ale jak mogę obsłużyć obiekt db SQLAlchemy?W jaki sposób tworzysz komponent wielokrotnego użytku z Flask-SQLAlchemy?

Ponieważ mój składnik musi być oddzielny, nie mogę po prostu zaimportować obiektu db. Ale nie sądzę, powinienem utworzyć obiekt db dwa razy. Jak zmieszać jego metadane z metadanymi w pozostałej części projektu?

Odpowiedz

3

Najpierw należy udostępnić metadata i nie używać kolby-sqlalchemy db.Model jako podstawy dla aplikacji wielokrotnego użytku.

Na sekundę musisz odtworzyć wszystkie klasy, rozszerzając je o nowe bazy z flask-sqlalchemy na wsparcie sygnałów, skrótów i innych rzeczy.

Integracja podstawy (może on być błędy):

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) 

Przykład kolby aplikacji z rozszerzeniem 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() 

przypadku some_model_base.py:

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

def init_metadata(metadata): 
    Base.metadata = metadata 

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

W tym przykładzie przetestowano tylko skrót db.create_all i SomeClass.query.

Przepraszamy za mój słaby angielski.

+0

Hm, muszę to wypróbować. Czy potrafisz znaleźć sposób na skonfigurowanie modeli w drugim module, aby mieć związek z modelami w programie głównym? –

+0

Myślę, że najlepiej to zrobić - zadeklaruj w swoich bazach danych aplikacji wielokrotnego użytku lub MixIns, a następnie zbuduj konkretne modele podklasując je. – estin

1

Należy użyć flask.current_app, jest to obiekt proxy, aby uzyskać dostęp do bieżącej aplikacji i jest to, co jest używane w niektórych rozszerzeniach. Tak, Twój kod będzie wyglądał tak:

from flask import current_app 
from flaskext.sqlalchemy import SQLAlchemy 

db = SQLAlchemy(current_app) 

a następnie użyć obiektu db jak można zwykle zrobić. Ale nie jestem pewien, czy to działałoby, gdyby użytkownik użył twojego modułu, a także musiał użyć flaskext.sqlalchemy, może to by było w konflikcie, sugerowałbym przetestowanie tego, aby upewnić się, że twój moduł będzie w 100% zgodny z każdą aplikacją flask .

Powiązane problemy