有什么好的Python ORM解决方案?[关闭]

问题:有什么好的Python ORM解决方案?[关闭]

我正在评估并考虑将CherryPy用于一个项目,该项目基本上是客户端(浏览器)的JavaScript前端,可与后端的Python Web服务进行通信。因此,我确实需要在后端实现快速,轻便的东西,我可以使用Python来实现,然后再通过ORM(浏览器的JSON)与PostgreSQL数据库对话。

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

任何人都具有使用不同Python ORM解决方案的经验,这些解决方案可以比较和对比其特性和功能,速度,效率等?

I’m evaluating and looking at using CherryPy for a project that’s basically a JavaScript front-end from the client-side (browser) that talks to a Python web service on the back-end. So, I really need something fast and lightweight on the back-end that I can implement using Python that then speaks to the PostgreSQL DB via an ORM (JSON to the browser).

I’m also looking at Django, which I like, since its ORM is built-in. However, I think Django might be a little more than I really need (i.e. more features than I really need == slower?).

Anyone have any experience with different Python ORM solutions that can compare and contrast their features and functionality, speed, efficiency, etc.?


回答 0

SQLAlchemy功能更强大,功能更强大(使用DataMapper模式)。Django ORM的语法更简洁,更易于编写(ActiveRecord模式)。我不了解性能差异。

SQLAlchemy还具有一个声明性层,该隐藏了一些复杂性,并使其具有类似于Django ORM的ActiveRecord样式语法。

我不会担心Django太“笨重”。它已经足够解耦,因此您可以在不需要导入其余部分的情况下使用ORM 。

就是说,如果我已经在Web层上使用CherryPy并且只需要一个ORM,那么我可能会选择SQLAlchemy。

SQLAlchemy is more full-featured and powerful (uses the DataMapper pattern). Django ORM has a cleaner syntax and is easier to write for (ActiveRecord pattern). I don’t know about performance differences.

SQLAlchemy also has a declarative layer that hides some complexity and gives it a ActiveRecord-style syntax more similar to the Django ORM.

I wouldn’t worry about Django being “too heavy.” It’s decoupled enough that you can use the ORM if you want without having to import the rest.

That said, if I were already using CherryPy for the web layer and just needed an ORM, I’d probably opt for SQLAlchemy.


回答 1

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

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

If you’re looking for lightweight and are already familiar with django-style declarative models, check out peewee: https://github.com/coleifer/peewee

Example:

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

Check the docs for more examples.


回答 2

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

Storm has arguably the simplest 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()

And it makes it painless to drop down into raw SQL when you need to:

store.execute('UPDATE bars SET bar_name=? WHERE bar_id like ?', []) 
store.commit()

回答 3

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

如果您打算使用CherryPy,您可能还会研究dejavu,就像Robert Brewer(现任CherryPy项目负责人)一样。我个人没有使用过它,但是我确实知道有些人喜欢它。

SQLObject使用ORM比使用SQLAlchemy容易一些,但是功能不那么强大。

就个人而言,除非计划在Django中编写整个项目,否则我不会使用Django ORM,但这只是我一个人。

I usually use SQLAlchemy. It’s pretty powerful and is probably the most mature python ORM.

If you’re planning on using CherryPy, you might also look into dejavu as it’s by Robert Brewer (the guy that is the current CherryPy project leader). I personally haven’t used it, but I do know some people that love it.

SQLObject is a little bit easier to use ORM than SQLAlchemy, but it’s not quite as powerful.

Personally, I wouldn’t use the Django ORM unless I was planning on writing the entire project in Django, but that’s just me.


回答 4

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

SQLAlchemy’s declarative extension, which is becoming standard in 0.5, provides an all in one interface very much like that of Django or Storm. It also integrates seamlessly with classes/tables configured using the datamapper style:

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

回答 5

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

We use Elixir alongside SQLAlchemy and have liked it so far. Elixir puts a layer on top of SQLAlchemy that makes it look more like the “ActiveRecord pattern” counter parts.


回答 6

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

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

This seems to be the canonical reference point for high-level database interaction in Python: http://wiki.python.org/moin/HigherLevelDatabaseProgramming

From there, it looks like Dejavu implements Martin Fowler’s DataMapper pattern fairly abstractly in Python.


回答 7

我认为您可能会看一下:

秋季

风暴

I think you might look at:

Autumn

Storm


回答 8

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

There is no conceivable way that the unused features in Django will give a performance penalty. Might just come in handy if you ever decide to upscale the project.


回答 9

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

I used Storm + SQLite for a small project, and was pretty happy with it until I added multiprocessing. Trying to use the database from multiple processes resulted in a “Database is locked” exception. I switched to SQLAlchemy, and the same code worked with no problems.


回答 10

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

SQLAlchemy is very, very powerful. However it is not thread safe make sure you keep that in mind when working with cherrypy in thread-pool mode.


回答 11

我会检查SQLAlchemy

它真的很容易使用,并且您使用的模型也不错。Django对它的ORM使用SQLAlchemy,但单独使用它可以让您充分利用它。

这是一个有关创建和选择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')>

I’d check out SQLAlchemy

It’s really easy to use and the models you work with aren’t bad at all. Django uses SQLAlchemy for it’s ORM but using it by itself lets you use it’s full power.

Here’s a small example on creating and selecting orm objects

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