2013-10-01 13 views
9

Przeczytałem flask-sqlalchemy or sqlalchemy, który zaleca użycie kolby-sqlalchemy z kolbą. Chcę zastosować to podejście.Jak korzystać z kolby-sqlalchemy z istniejącym modelem sqlalchemy?

Mam jednak istniejący model napisany dla skryptów wiersza poleceń, który jest oparty na declarative_base sqlalchemy za np

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

Chcę nadal być w stanie używać skryptów wiersza polecenia z tego modelu, ale również chcesz zbudować aplikację internetową wokół modelu.

Czy istnieje sposób na rozszerzenie istniejącego modelu, aby skorzystać z rozszerzenia kolby-sqlalchemy? Czy powinienem po prostu rzucić własną i użyć ScopedSession sqlalchemy?

+0

Czy byłoby problem z przepisaniem skryptów wiersza poleceń przy użyciu modelu kolby-sqlalchemy? –

+0

Nie wiem - nie użyłem wcześniej kolby lub kolby-alchemii i nie znam efektów ubocznych. Czy skrypty powinny zostać przepisane, czy tylko importowany model? Powinienem też wspomnieć, że używam alembic do śledzenia zmian w bazie danych, na wypadek, gdyby były tam problemy ze zgodnością. –

Odpowiedz

9

Obecnie jest to coś, co nie jest dobrze obsługiwane, ale nie jest niemożliwe. Zobacz this issue na liście problemów Flask-SQLAlchemy, która przyznaje, że obecna implementacja rozszerzenia sprawia, że ​​ta sytuacja jest bardziej bolesna niż im się wydaje. Mam nadzieję, że będzie to lepiej obsługiwane w przyszłości (gdy ustali się stała ścieżka migracji i nowy interfejs API).

Kwestia ta wydaje następujący przykładowy kod:

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) 

Istnieje kilka rzeczy do odnotowania tutaj:

pierwsze, tracisz zdolność do User.query (ponieważ użytkownik został stworzony przy użyciu własnego deklaratywnej base), wraz z wszystkimi innymi rzeczami, które daje Flask-SQLAlchemy pod nr db.Model (takimi jak możliwość automatycznego generowania nazw tabel i metod, takich jak first_or_404()).

Po drugie, za każdym razem, gdy trzeba wykonać czynności związane z metadanymi (takie jak drop_all lub create_all), nie można korzystać z metod Flask-SQLAlchemy. Musisz użyć oryginalnych metadanych związanych z silnikiem Flask-SQLAlchemy.

Nie próbowałem tego sam, więc nie jestem pewien, czy są jakieś inne podejrzenia do tego podejścia. Możesz wziąć udział w tym bilecie, jeśli go znajdziesz.

+0

Dzięki za wskaźnik do problemu. Mogę wykonać eksperyment, ale zdecydowanie łatwiej, jeśli znasz tę odpowiedź: jeśli przepisuję ten model za pomocą db.model z kolby-alchemii, a nie Base, z tym, że łamie on skrypty wiersza poleceń? –

+0

@Lou_K: Prawdopodobnie nie "zepsute" per se, ale kiedy spróbujesz je uruchomić, być może będziesz musiał wykonać dodatkową pracę, konfigurując aplikację Flask, zanim mięso skryptu zostanie uruchomione. –

+0

@ Mark_Hildreth: Mogę spróbować. Jeśli to staje się uciążliwe, może uda mi się wykonać ten sam plik źródłowy dla modelu, ale zależy to od pewnych informacji o środowisku (jakiejś konfiguracji zewnętrznej względem Pythona, ustawionej przez linię poleceń lub przez aplikację internetową) w celu zaimportowania właściwych rzeczy, i zadeklaruj Bazę odpowiednio, w zależności od tego, czy jest używana przez skrypt wiersza poleceń, czy aplikację kolb. Nie czuje się jednak zbyt elegancko. Trzeba to przemyśleć dokładnie, aby upewnić się, że oba systemy nie kolidują ze sobą w jakiś sposób. –