2015-05-08 13 views
9

Avevo un piccolo servizio Web creato utilizzando e Flask-SQLAlchemy che conteneva solo un modello. Ora desidero utilizzare lo stesso database, ma con un'app della riga di comando, quindi mi piacerebbe eliminare la dipendenza Flask.Utilizzo di Flask-SQLAlchemy senza pallone

Il mio modello è simile al seguente:

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 

Dal db non sarà più un riferimento a flask.ext.sqlalchemy.SQLAlchemy(app), come posso convertire il mio modello da utilizzare solo SQLAlchemy. Esiste un modo per le due applicazioni (una con Flask-SQLAlchemy l'altra con SQLAlchemy) per utilizzare lo stesso database?

+0

Il * banca dati * dovrebbe essere indipendente dal * modelli * o strato ORM che stai utilizzando. – Makoto

+0

Sì, ho capito. Sto cercando un modo per riutilizzare il codice sia in flask che in non flask senza dover modificare le definizioni del mio modello in modo significativo. – amccormack

+0

Non c'è nulla di relativo al pallone nel modello. Tutto ciò che serve è creare una connessione db e importare il modello in una bottiglia o in un'app non-pallone. Metterei semplicemente il modello in 'models.py' così (in realtà basta spostare il precedente dal file .py principale del flask e importare/istanziare IPentry quando necessario). –

risposta

0

controllare questo github.com/mardix/active-alchemy

Active-Alchemy è un wrapper agnostico framework per SQLAlchemy che lo rende davvero facile da usare implementando un semplice record attivo come api, mentre usa ancora la db.session sotto. Ispirato da Flask-SQLAlchemy

0

si può fare questo per sostituire 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) 

poi per creare le tabelle:

base.metadata.create_all() 
1

questo non risponde completamente alla tua domanda, perché lo fa non rimuovere la dipendenza da Flask, ma è possibile utilizzare SqlAlchemy in script e test solo per non in esecuzione l'app 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 

Una difficoltà che si possono incontrare è il requisito di utilizzare db.Model come classe base per i vostri modelli, se si vuole indirizzare la web app e gli script indipendenti utilizzando la stessa base di codice. Il modo migliore per affrontarlo è usare il polimorfismo dinamico e avvolgere la definizione della classe in una funzione.

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

Come si costruisce la classe di runtime nella funzione, è possibile passare in diverse SqlAlchemy casi. L'unico svantaggio è che devi chiamare la funzione per costruire la classe prima di usarla.

db = SqlAlchemy(...) 
IpEntry = get_ipentry(db) 
IpEntry.query.filter_by(id=123).one()