232

我正在评估并考虑将 CherryPy 用于一个项目,该项目基本上是来自客户端(浏览器)的 JavaScript 前端,它与后端的 Python Web 服务通信。所以,我真的需要一些快速和轻量级的后端,我可以使用 Python 实现,然后通过 ORM(JSON 到浏览器)与 PostgreSQL DB 对话。

我也在看我喜欢的 Django,因为它的 ORM 是内置的。但是,我认为 Django 可能比我真正需要的要多一点(即比我真正需要的功能更多 == 更慢?)。

任何人都对不同的 Python ORM 解决方案有任何经验,可以比较和对比它们的特性和功能、速度、效率等吗?

4

12 回答 12

122

如果您正在寻找轻量级并且已经熟悉 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')

查看文档以获取更多示例。

于 2011-09-16T02:58:48.330 回答
121

SQLAlchemy 功能更全面,功能更强大(使用 DataMapper 模式)。Django ORM 具有更简洁的语法并且更易于编写(ActiveRecord 模式)。我不知道性能差异。

SQLAlchemy 还有一个声明层,它隐藏了一些复杂性,并为其提供了一种更类似于 Django ORM 的 ActiveRecord 样式的语法。

我不会担心 Django “太重”。它已经足够解耦,您可以根据需要使用 ORM,而无需导入其余部分

也就是说,如果我已经将 CherryPy 用于 Web 层并且只需要一个 ORM,我可能会选择 SQLAlchemy。

于 2008-09-10T13:37:05.410 回答
81

Storm可以说是最简单的 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()
于 2008-12-21T18:36:20.770 回答
29

我通常使用SQLAlchemy。它非常强大,可能是最成熟的python ORM。

如果您打算使用 CherryPy,您还可以研究由 Robert Brewer(目前 CherryPy 项目负责人)编写的 dejavu 我个人没有使用过它,但我确实知道一些喜欢它的人。

SQLObject比 SQLAlchemy 更易于使用 ORM,但它的功能并不那么强大。

就个人而言,除非我打算用 Django 编写整个项目,否则我不会使用 Django ORM,但这只是我。

于 2008-09-10T15:02:58.310 回答
17

SQLAlchemy 的声明式扩展在 0.5 中成为标准,提供了一个与 Django 或 Storm 非常相似的多合一接口。它还与使用 datamapper 样式配置的类/表无缝集成:

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()
于 2009-01-02T17:56:37.930 回答
10

我们将Elixir与 SQLAlchemy 一起使用,并且到目前为止一直很喜欢它。Elixir 在 SQLAlchemy 之上放置了一层,使其看起来更像“ActiveRecord 模式”计数器部件。

于 2008-09-11T03:44:54.017 回答
5

这似乎是 Python 中高级数据库交互的规范参考点: http ://wiki.python.org/moin/HigherLevelDatabaseProgramming

从那里看,Dejavu似乎在 Python 中相当抽象地实现了 Martin Fowler 的 DataMapper 模式。

于 2011-03-21T23:29:54.587 回答
1

我想你可能会看:

秋天

风暴

于 2008-09-10T04:56:53.757 回答
1

无法想象 Django 中未使用的功能会降低性能。如果您决定升级项目,可能会派上用场。

于 2008-10-09T06:41:09.030 回答
0

我在一个小项目中使用了 Storm + SQLite,并且对它非常满意,直到我添加了多处理。尝试从多个进程中使用数据库会导致“数据库已锁定”异常。我切换到 SQLAlchemy,同样的代码没有问题。

于 2011-02-05T18:28:40.360 回答
-1

SQLAlchemy 非常非常强大。但是,它不是线程安全的,请确保在线程池模式下使用cherrypy 时牢记这一点。

于 2010-03-24T19:37:47.357 回答
-7

我会检查SQLAlchemy

它非常易于使用,并且您使用的模型一点也不差。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')>
于 2008-09-10T05:19:34.780 回答