题
我正在评估和考虑在一个项目中使用 CherryPy,该项目基本上是客户端(浏览器)的 JavaScript 前端,与后端的 Python Web 服务进行通信。因此,我确实需要一些快速且轻量级的后端功能,我可以使用 Python 实现它,然后通过 ORM(浏览器的 JSON)与 PostgreSQL DB 进行交互。
我也在关注 Django,我喜欢它,因为它的 ORM 是内置的。然而,我认为 Django 可能比我真正需要的要多一点(即比我真正需要的功能更多==更慢?)。
任何人都有使用不同 Python ORM 解决方案的经验,可以比较和对比它们的特性和功能、速度、效率等吗?
解决方案
SQLAlchemy 功能更全面、更强大(使用 DataMapper 模式)。Django ORM 具有更清晰的语法并且更易于编写(ActiveRecord 模式)。我不知道性能差异。
SQLAlchemy 还有一个 声明层 它隐藏了一些复杂性并赋予它更类似于 Django ORM 的 ActiveRecord 风格语法。
我不会担心Django“太重”。它已足够分离,可以在不必导入其余的情况下使用ORM。
也就是说,如果我已经在 Web 层使用 CherryPy 并且只需要一个 ORM,我可能会选择 SQLAlchemy。
其他提示
如果您正在寻找轻量级并且已经熟悉 django 风格的声明性模型,请查看 peewee:https://github.com/coleifer/peewee
例子:
import datetime
from peewee import *
class Blog(Model):
name = CharField()
class Entry(Model):
blog = ForeignKeyField(Blog)
title = CharField()
body = TextField()
pub_date = DateTimeField(default=datetime.datetime.now)
# query it like django
Entry.filter(blog__name='Some great blog')
# or programmatically for finer-grained control
Entry.select().join(Blog).where(Blog.name == 'Some awesome blog')
检查 文档 了解更多示例。
风暴 可以说有最简单的 API:
from storm.locals import *
class Foo:
__storm_table__ = 'foos'
id = Int(primary=True)
class Thing:
__storm_table__ = 'things'
id = Int(primary=True)
name = Unicode()
description = Unicode()
foo_id = Int()
foo = Reference(foo_id, Foo.id)
db = create_database('sqlite:')
store = Store(db)
foo = Foo()
store.add(foo)
thing = Thing()
thing.foo = foo
store.add(thing)
store.commit()
当您需要执行以下操作时,可以轻松地使用原始 SQL:
store.execute('UPDATE bars SET bar_name=? WHERE bar_id like ?', [])
store.commit()
SQLAlchemy 的 陈述性的 扩展在 0.5 中成为标准,提供了一个非常类似于 Django 或 Storm 的一体化接口。它还与使用数据映射器样式配置的类/表无缝集成:
Base = declarative_base()
class Foo(Base):
__tablename__ = 'foos'
id = Column(Integer, primary_key=True)
class Thing(Base):
__tablename__ = 'things'
id = Column(Integer, primary_key=True)
name = Column(Unicode)
description = Column(Unicode)
foo_id = Column(Integer, ForeignKey('foos.id'))
foo = relation(Foo)
engine = create_engine('sqlite://')
Base.metadata.create_all(engine) # issues DDL to create tables
session = sessionmaker(bind=engine)()
foo = Foo()
session.add(foo)
thing = Thing(name='thing1', description='some thing')
thing.foo = foo # also adds Thing to session
session.commit()
我们用 灵丹妙药 与 SQLAlchemy 一起使用,并且到目前为止很喜欢它。Elixir 在 SQLAlchemy 之上放置了一层,使其看起来更像“ActiveRecord 模式”对应部分。
这似乎是 Python 中高级数据库交互的规范参考点:http://wiki.python.org/moin/HigherLevelDatabaseProgramming
从那里看来, 德贾武 在 Python 中相当抽象地实现了 Martin Fowler 的 DataMapper 模式。
Django 中未使用的功能不会造成性能损失。如果您决定升级项目,可能会派上用场。
SQLAlchemy 非常非常强大。然而,它不是线程安全的,请确保在线程池模式下使用 Cherrypy 时记住这一点。
我在一个小项目中使用了 Storm + SQLite,并且对它非常满意,直到我添加了多处理。尝试从多个进程使用数据库导致“数据库已锁定”异常。我切换到 SQLAlchemy,相同的代码没有任何问题。
我想看看 SQL炼金术
它真的很容易使用,而且你使用的模型一点也不差。 Django 使用 SQLAlchemy 作为 ORM 但单独使用它可以让你发挥它的全部力量。
这是一个创建和选择 orm 对象的小例子
>>> ed_user = User('ed', 'Ed Jones', 'edspassword')
>>> session.add(ed_user)
>>> our_user = session.query(User).filter_by(name='ed').first()
>>> our_user
<User('ed','Ed Jones', 'edspassword')>