SQLAlchemy est alambiqué?
Cela peut semble plutôt argumentatif, mais je suis juste allé à travers SQLAlchemy de ORM tutoriel et s'est terminé avec le code suivant:
from sqlalchemy import create_engine
from sqlalchemy import Table, Column, Integer, String, MetaData, ForeignKey
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
engine = create_engine('sqlite:///:memory:', echo=True)
metadata = MetaData()
users_table = Table('users', metadata,
Column('id', Integer, primary_key=True),
Column('name', String),
Column('fullname', String),
Column('password', String)
)
metadata.create_all(engine)
Base = declarative_base()
class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
name = Column(String)
fullname = Column(String)
password = Column(String)
def __init__(self, name, fullname, password):
self.name = name
self.fullname = fullname
self.password = password
def __repr__(self):
return "<User('%s','%s', '%s')>" % (self.name, self.fullname, self.password)
users_table = User.__table__
metadata = Base.metadata
Session = sessionmaker(bind=engine)
Session = sessionmaker()
Session.configure(bind=engine) # once engine is available
session = Session()
# actually using the ORM isn't too bad..
ed_user = User('ed', 'Ed Jones', 'edspassword')
session.add(ed_user)
our_user = session.query(User).filter_by(name='ed').first()
print our_user
session.add_all([
User('wendy', 'Wendy Williams', 'foobar'),
User('mary', 'Mary Contrary', 'xxg527'),
User('fred', 'Fred Flinstone', 'blah')])
ed_user.password = 'f8s7ccs'
print session.dirty
print session.new
session.commit()
for instance in session.query(User).order_by(User.id):
print instance.name, instance.fullname
for name, fullname in session.query(User.name, User.fullname):
print name, fullname
Cela semble incroyablement compliqué pour un Hello World table, surtout par rapport à l'à peu près similaire SQLObject code:
from sqlobject import SQLObject, StringCol, sqlhub, connectionForURI
sqlhub.processConnection = connectionForURI('sqlite:/:memory:')
class Person(SQLObject):
fname = StringCol()
mi = StringCol(length=1, default=None)
lname = StringCol()
Person.createTable()
p = Person(fname="John", lname="Doe")
p.mi = 'Q'
p2 = Person.get(1)
print p2
print p2 is p
Je comprends SQLAlchemy est "le plus fort", mais que la puissance semble venir à un coût, ou ai-je raté quelque chose?
- L'alimentation a un coût? Que dites-vous?
- SQLAlchemy de puissance se fait au prix de la simplicité d'utilisation?
- Essayez Élixir comme mentionné ci-dessous, votre Bonjour tout le Monde sera très similaire à SQLObject, et vous serez toujours en mesure d'accéder à la SQLAlchemy couche. J'ai utilisé SQLObject et frustré par ses limites, et je suis très heureux avec l'Élixir de la mesure (il manque un peu de documentation et de soutien, mais l'utilisateur de base semble limité malheureusement).
- On n'a pas tout simplement ajouter un point d'interrogation à une instruction.
Vous devez vous connecter pour publier un commentaire.
Bien, il y a une chose qui vous manque: le tutoriel que vous mentionnez n'est pas "construire" un exemple complet, les différents bouts de code ne sont pas destinés à être concaténés dans un seul fichier source. Plutôt, ils décrivent les différentes manières de la bibliothèque peut être utilisée. Pas besoin d'essayer de faire la même chose encore et encore vous-même.
Laissant de côté le fait-de-la-orm partie de votre exemple, le code pourrait ressembler à ceci:
Le "déclaratif" extension prend en charge la définition de la table et de la cartographie à votre classe, vous n'avez pas besoin de déclarer le
users_table
vous-même. L'Utilisateur de la classe permettra également à l'instanciation avec le mot-clé arguments, commeUser(name="foo")
, (mais pas les arguments de position tout de même).J'ai aussi ajouté l'utilisation de scoped_session, ce qui signifie que vous pouvez utiliser directement
Session
sans avoir à instancier (il va instancier une nouvelle session si il n'est pas déjà présent dans le thread en cours, ou la réutilisation de l'existant contraire)scoped_session
pour rien; Sauf si vous savez pourquoi vous avez besoin de thread local storage, vous devez instancier la session explicitement et de les passer en tant que de besoin.scoped_session
prend toutes les conjectures et inutile argument en passant de l'utilisation de sessions. Vous venez de définir votrescoped_session
classe au début, puis instancier partout où vous avez besoin d'accéder à la session, et le système fait le reste. J'ai trouvé que c'était très pratique pour toutes les applications web que j'ai écrit.scoped_session
peut être un bon ajustement; tant que les besoins de votre application exactement session par demande, et à l'aide de votre un une demande par modèle de thread. Si ce n'est pas vrai, vous pourriez avoir besoin pour opérer sur la base de données en dehors d'un contexte de demande; si vous avez besoin de coordonner les opérations à travers de multiples bases de données, si vous effectuez un travail dans un système de manière à améliorer les performances, cette hypothèse commence à se décomposer.Les exemples de code que vous donnez ne sont pas des pommes avec des pommes. La SQLAlchemy version pourrait être réduite vers le bas un peu:
Vous pouvez également trouver des Elixir plus comme SQLObject (mais puisque je n'ai pas utilisé non plus, c'est juste une supposition).
Ne pas avoir utilisé SQLObject à tous, je ne peux pas commenter sur ce que SA fait mieux. Mais j'ai eu de grandes expériences avec SA, surtout lorsqu'il s'agit compliqué, dans le monde réel, les anciens schémas. Il fait un bon travail de venir avec une bonne requêtes SQL par défaut, et il y a beaucoup de façons de les améliorer.
J'ai trouvé SQLAlchemy de l'auteur elevator pitch de tenir assez bien dans la pratique.
Avoir utilisé SQLObject (et que par la lecture de SQLAlchemy), je peux dire que l'un des SQLObject des points forts est la facilité et la simplicité avec laquelle vous pouvez obtenir des choses faites. Aussi, un excellent soutien est fourni par le groupe email (https://lists.sourceforge.net/lists/listinfo/sqlobject-discuss) qui obtient des réponses pour vous assez rapidement.
Essayer Rapide ORM, c'est encore plus simple:
Rapide ORM est construit sur SQLAlchemy, donc, on pourrait dire que SQLAlchemy pourrait être aussi simple que de SQLObject.
Bien, SQLAlchemy est divisé en différentes parties, la base principale de la partie tout simplement les poignées de la DB, en transformant votre python construit des requêtes en langage SQL pour les sous-jacents DB. Ensuite, il ya la prise en charge des sessions, l'orm, et la nouvelle syntaxe déclarative.
Ressemble SQLObject (je ne peux pas dire pour sûr, ne l'ai pas utilisé depuis de nombreuses années, et même alors, seulement une fois) saute plus et ne l'ORM partie tout de suite. Souvent, cela rend les choses plus faciles pour de simples données (que vous pouvez sortir avec dans la plupart des cas), mais SQLAlchemy permet plus complexe db mises en page, et de descendre et sale avec la db si vous en avez vraiment besoin.
vous dire "alambiqué".... quelqu'un pourrait dire "flexible". Parfois, vous devez parfois vous n'avez pas. N'est-il pas incroyable que vous avez un choix?