Je suis nouveau dans les deux flask et sqlalchemy, je commence juste à travailler sur une application flask, et j'utilise sqlalchemy pour l'instant. Je me demandais s'il y avait tout avantage significatif que je peux tirer de l'utilisation de flask-sqlalchemy vs sqlalchemy. Je n'ai pas trouvé suffisamment de motivations dans http://packages.python.org/Flask-SQLAlchemy/index.html ou peut-être que je ne l'ai pas fait comprendre la valeur !! J'apprécierais vos clarifications.
La principale caractéristique du Flask-SQLAlchemy
est une bonne intégration avec l'application Flask - il crée et configure le moteur, la connexion et la session et le configure pour qu'il fonctionne avec l'application Flask.
Cette configuration est assez complexe car nous devons créer le session de portée et le gérer correctement en fonction du cycle de vie de la demande/réponse de l'application Flask).
Dans le monde idéal, ce serait la seule caractéristique de Flask-SQLAlchemy
, mais en fait, cela ajoute peu de choses. Voici un bon article de blog avec un aperçu d'eux: Demystifying Flask-SQLAlchemy .
Lorsque j'ai travaillé pour la première fois avec Flask et SQLAlchemy, je n'aimais pas cette surcharge. Je suis allé et j'ai extrait le code de gestion de session de l'extension. Cette approche fonctionne, même si j'ai découvert que c'est assez difficile de faire cette intégration correctement.
Donc, l'approche la plus simple (qui est utilisée dans un autre projet sur lequel je travaille) consiste simplement à supprimer le Flask-SQLAlchemy
in et n'utilisez aucune des fonctionnalités supplémentaires qu'il fournit. Vous aurez le db.session
et vous pouvez l'utiliser comme s'il s'agissait d'une configuration pure SQLAlchemy
.
Pour être honnête, je ne vois aucun avantage. À mon humble avis, Flask-SQLAlchemy crée une couche supplémentaire dont vous n'avez pas vraiment besoin. Dans notre cas, nous avons une application assez complexe Flask avec plusieurs bases de données/connexions (maître-esclave) utilisant à la fois ORM et Core où, entre autres, nous devons contrôler nos sessions/transactions DB ( par exemple, modes dryrun vs commit) Flask-SQLAlchemy ajoute des fonctionnalités supplémentaires telles que la destruction automatique de la session en supposant certaines choses pour vous, ce qui n'est souvent pas ce dont vous avez besoin.
La documentation SQLAlchemy indique clairement que vous devez utiliser Flask-SQLAlchemy (surtout si vous ne comprenez pas ses avantages!):
des produits [...] tels que Flask-SQLAlchemy [...] SQLAlchemy recommande fortement que ces produits soient utilisés tels qu'ils sont disponibles.
Cette citation et une motivation détaillée que vous pouvez trouver dans la deuxième question de la Session FAQ .
Flask-SQLAlchemy vous offre un certain nombre de fonctionnalités supplémentaires que vous auriez autrement pu vous implémenter en utilisant SQLAlchemy.
apply_driver_hacks
qui définit automatiquement les valeurs par défaut saines comme Thigs comme la taille du pool MySQLDéfinissez automatiquement les noms de table. Flask-SQLAlchemy définit automatiquement les noms de vos tables en convertissant votre ClassName
> class_name
cela peut être remplacé en définissant __tablename__
classe Élément de liste
comme @schlamar le suggère, Flask-SqlAlchemy est sans aucun doute une bonne chose. Je voudrais simplement ajouter un peu de contexte supplémentaire au point soulevé ici.
Ne vous sentez pas comme si vous choisissez l'un plutôt que l'autre. Par exemple, disons que nous voulons récupérer tous les enregistrements d'une table à l'aide d'un modèle utilisant Flask-Sqlalchemy. C'est aussi simple que
Model.query.all()
Pour beaucoup de cas simples, Flask-Sqlalchemy va être totalement bien. Le point supplémentaire que je voudrais faire est que si Flask-Sqlalchemy ne fait pas ce que vous voulez, il n'y a aucune raison pour que vous ne puissiez pas utiliser SqlAlchemy directement.
from myapp.database import db
num_foo = db.session.query(func.count(OtherModel.id)).filter(is_deleted=False).as_scalar()
db.session.query(Model.id, num_foo.label('num_foo')).order_by('num_foo').all()
Comme vous pouvez le voir, nous pouvons facilement passer de l'un à l'autre sans problème et dans le deuxième exemple, nous utilisons en fait les modèles définis Flask-Sqlalchemy.
Voici un exemple d'un avantage que la fiole-sqlalchemy vous donne par rapport à la simple sqlalchemy.
Supposons que vous utilisez flask_user.
flask_user automatise la création et l'authentification des objets utilisateur, il doit donc accéder à votre base de données. La classe UserManager fait cela en appelant à quelque chose appelé un "adaptateur" qui résume les appels de la base de données. Vous fournissez un adaptateur dans le constructeur UserManager et l'adaptateur doit implémenter ces fonctions:
class MyAdapter(DBAdapter):
def get_object(self, ObjectClass, id):
""" Retrieve one object specified by the primary key 'pk' """
pass
def find_all_objects(self, ObjectClass, **kwargs):
""" Retrieve all objects matching the case sensitive filters in 'kwargs'. """
pass
def find_first_object(self, ObjectClass, **kwargs):
""" Retrieve the first object matching the case sensitive filters in 'kwargs'. """
pass
def ifind_first_object(self, ObjectClass, **kwargs):
""" Retrieve the first object matching the case insensitive filters in 'kwargs'. """
pass
def add_object(self, ObjectClass, **kwargs):
""" Add an object of class 'ObjectClass' with fields and values specified in '**kwargs'. """
pass
def update_object(self, object, **kwargs):
""" Update object 'object' with the fields and values specified in '**kwargs'. """
pass
def delete_object(self, object):
""" Delete object 'object'. """
pass
def commit(self):
pass
Si vous utilisez flask-sqlalchemy, vous pouvez utiliser le SQLAlchemyAdapter intégré. Si vous utilisez sqlalchemy (not-flask-sqlalchemy), vous pouvez faire différentes hypothèses sur la façon dont les objets sont enregistrés dans la base de données (comme les noms des tables), vous devrez donc écrire votre propre classe d'adaptateur.