5 Stimmen

Wie erstellt man eine wiederverwendbare Komponente mit Flask-SQLAlchemy?

Nehmen wir an, ich habe einen Teil meiner Flask-App, den ich herausziehen und in mehreren verschiedenen Projekten verwenden möchte. Er hat SQLAlchemy-Modelle, die Flask-SQLAlchemy verwenden, sowie Ansichten und Vorlagen. Ich kann die app.route-Dekoratoren mit einem Modul abrufen, aber wie kann ich das SQLAlchemy-DB-Objekt behandeln?

Da meine Komponente separat sein muss, kann ich nicht einfach das DB-Objekt importieren. Aber ich denke nicht, dass ich das DB-Objekt zweimal erstellen sollte. Wie würde ich seine Metadaten mit den Metadaten im Rest des Projekts mischen?

3voto

estin Punkte 2851

Zuerst müssen Sie teilen metadata und verwenden Sie nicht flask-sqlalchemy db.Model als Basis für Ihre wiederverwendbare Anwendung.

Als zweites muss man alle Klassen neu erstellen, indem man sie um neue Basen von flask-sqlalchemy erweitert, um Signale, Abkürzungen und andere Dinge zu unterstützen.

Integrieren Sie Basen (es kann fehlerhaft sein):

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)

Beispiel einer Flask-Anwendung mit Sqlalchemy-Erweiterung:

# -*- 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()

Wo some_model_base.py:

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

def init_metadata(metadata):
    Base.metadata = metadata

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

In diesem Beispiel wurden nur die Verknüpfung db.create_all und SomeClass.query getestet.

Entschuldigung für mein schlechtes Englisch.

1voto

mdeous Punkte 16513

Sie sollten Folgendes verwenden flask.current_app Es handelt sich um ein Proxy-Objekt für den Zugriff auf die aktuelle Anwendung, das in einigen Erweiterungen verwendet wird. Ihr Code würde also etwa so aussehen:

from flask import current_app
from flaskext.sqlalchemy import SQLAlchemy

db = SQLAlchemy(current_app)

und verwenden Sie dann Ihre db Objekt, wie Sie es normalerweise tun würden. Aber ich bin mir nicht sicher, ob dies funktionieren würde, wenn der Benutzer Ihr Modul verwendet und auch benötigt, um flaskext.sqlalchemy Ich würde vorschlagen, dies zu testen, um sicher zu sein, dass Ihr Modul zu 100% kompatibel mit allen anderen Modulen ist. flask Anwendung.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X