有哪些好的Python ORM解决方案?

254
我正在评估并考虑使用CherryPy来完成一个项目,这个项目基本上是一个JavaScript前端(通过客户端浏览器)与后端Python Web服务进行交互。因此,我需要在后端使用Python实现一个快速且轻量级的解决方案,然后通过ORM与PostgreSQL数据库通信(通过JSON传递给浏览器)。
我也正在看Django,我很喜欢它,因为它的ORM已经内置了。但是,我认为Django可能比我实际需要的更多一些功能(即我不需要的功能会导致速度变慢?)。
请问有没有人对不同的Python ORM解决方案有经验,并可以比较和对比它们的功能、速度、效率等方面?

3
PonyORM 看起来非常不错。 - Niklas R
对象关系映射(ORM)已经在许多编程语言中非常流行,是SQL的最佳替代方案之一。我受到方法链接风格的启发,为我的TRIADB项目创建了CQL。healis.eu/triadb/#latest-release - Athanassios
你想看一下PonyORM。 另外,与此无关的是,在OpenAPI和GH Co-pilot席卷全球的情况下,Stackoverflow变得越来越不相关了。(例如:尽管有十几个人回答了这个问题,但将其标记为不相关) - Louis Duran
12个回答

138
如果你正在寻找轻量级的ORM,并且已经熟悉了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')

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


134

SQLAlchemy是一个更全面功能强大的ORM框架(使用DataMapper模式)。Django ORM拥有更清晰的语法,更易于编写(ActiveRecord模式)。我不知道它们在性能上有什么区别。

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

我不会担心Django会“太重”。它与Web层解耦得足够好,你可以在不必导入其他内容的情况下,如果需要的话使用ORM

话虽如此,如果我已经在使用CherryPy进行Web层开发,而只需要一个ORM,我可能会选择SQLAlchemy。


7
如果您不喜欢 Django 的 ORM,并想使用 SA,例如,那么您将失去很多 Django 的功能,比如 admin。这不是致命的问题,但会让你感到有点困扰。 - Gregg Lind
29
没错,但这与问题无关,问题只是关于选择Python ORM,而不是自动生成的管理界面或其他框架组件。 - Carl Meyer
8
我认为SQLAlchemy一点也不轻巧,虽然它可以非常快速。我会介绍我的项目,它叫做peewee,可以与postgres通信。最近还添加了支持Django风格查询的功能!http://charlesleifer.com/docs/peewee/ - coleifer
3
请注意,Django ORM 不支持复合主键,而 SQLAlchemy 支持。 - Marcin Kapusta
1
@yegle,我对你的评论感到困惑。我不理解这个逻辑。在文档中“难以找到ORDER BY DESC的说明”如何暗示“不适合活动记录模式”? - jpmc26
显示剩余3条评论

85

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

1
值得注意的是,Storm目前仅支持MySQL和PostgreSQL。但是,Storm正在开发Oracle支持。 - Jason Baker
17
它也支持SQLite,正如上面的例子所示。 - shearichard
2
quick_orm与Storm一样简单,并且它是建立在SQLAlchemy之上的,因此也非常强大:http://pypi.python.org/pypi/quick_orm。免责声明:我是quick_orm的作者。 - Tyler Liu
谢谢提供的示例。我有一个关于Storm和多对一关系的问题。我正在按照步骤进行操作,将引用放在类外面的文件末尾,然后导入其他类,在另一个类中导入当前类,这样就会创建一个循环导入,但我不知道还有什么其他方法可以解决? - Matilda
10
Storm没有维护。我不会在新项目中使用它。 - Matthias Urlichs
4
此外,似乎没有适用于Python 3的Storm。 - ygormutti

29

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

如果你打算使用CherryPy,你也可以看一下Dejavu,因为它是由Robert Brewer(目前的CherryPy项目负责人)开发的。我个人没有使用过它,但我知道有些人很喜欢。

SQLObject比SQLAlchemy更容易使用,但功能不如后者强大。

对于我个人而言,除非打算在Django中编写整个项目,否则我不会使用Django ORM,但这只是我的个人看法。


SQLObject非常棒 - 使用简单,独立于数据库,而且它实际上可以为你创建表格!(我很懒)。 - Lucas Jones
1
@Lucas - 那么SQLAlchemy能够... - Jason Baker
就我所记得的,我只是一般性地赞扬SQLObject。不过那是很久以前的事了... :) - Lucas Jones
@Lucas - 我也是这么想的。只是想记录一下。 :-) - Jason Baker

17

SQLAlchemy的declarative扩展,在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()

但是,如果存在许多关系,例如一对多、多对多、表继承等,情况就变得非常复杂。您必须手动编写大量代码来处理它们。请查看我的快速ORM答案。它可以节省您的时间。 - Tyler Liu
20
Tyler建议SQLAlchemy的创建者使用Quick ORM。 - Anthony Briggs
5
让我想起数年前Usenet上的某个人,与dmr@alice争论他并没有真正理解C语言。 - Peter Rowell
@AnthonyBriggs,请查看这张幻灯片,你就会明白为什么quick_orm比SQLAlchemy更擅长处理复杂的关系:http://www.slideshare.net/tyler4long/quickorm - Tyler Liu
1
看起来 quick_orm 已经死了 10 年了... https://github.com/tylerlong/quick_orm - Hugh Perkins

10

我们使用Elixir和SQLAlchemy一起使用,并且迄今为止很喜欢它。 Elixir在SQLAlchemy的基础上添加了一个层次结构,使其更像“ActiveRecord模式”的对应物。


2
SQLAlchemy支持开箱即用的面向对象编程和函数式编程风格,Elixir在此基础上添加了声明式编程风格(主要用于模型声明,但可以扩展)。 - muhuk

7

我对Dejavu产生了兴趣并查看了一下,只是稍微看了看。文档非常稀少(引用:“对于表示层,你必须自己摸索”),因此我认为它只适合高级用户使用。 - r4.

1

在Django中,未使用的功能不可能会导致性能损失。如果您决定升级项目,这些功能可能会派上用场。


10
有一种可以想象的方法。 - bukzor

1

秋季可能比Storm更容易,但Storm包含许多Autumn没有的功能。这两个选项都有有限的文档,尽管Storm正在快速修复。 - alecwh
谢谢,Autumn看起来非常漂亮和吸引人,但是它没有任何文档,这对我来说是无法接受的。 - temoto
1
我刚刚尝试了Autumn页面上的一些示例,它们甚至不能与我的软件包管理器安装的代码版本一起使用。Google组中的帖子也很旧。看起来这个项目正在缓慢地死亡。不建议使用它。 - Jason Miesionczek
另一方面,Storm 快速成为我首选的 ORM。文档越来越好,API 简洁明了,虽然我更习惯 Django ORM 使用的 ActiveRecord 模式,但我发现 Storm 很容易上手。 - Jason Miesionczek
1
Autumn似乎已经有一年没有任何活动了。http://groups.google.com/group/autumn-orm - Sridhar Ratnakumar

0
我曾经在一个小项目中使用Storm + SQLite,一直非常满意,直到我加入了多进程处理。由于尝试从多个进程访问数据库,结果导致了“数据库已锁定”的异常。后来我改用SQLAlchemy,同样的代码就可以无任何问题地运行了。

9
公平地说,SQLite 并不是为并发访问而设计的。 - Xiong Chiamiov
3
@Xion +1。SQLITE是一个只有一个文件,没有守护进程运行的数据库。 - Bite code

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接