Які хороші рішення для Python ORM? [зачинено]


209

Я оцінюю і дивлюся на використання CherryPy для проекту, який в основному є фронтальним кодом JavaScript з боку клієнта (браузера), який спілкується з веб-сервісом Python на задній частині. Отже, мені дуже потрібно щось швидке і легке на задньому плані, що я можу реалізувати за допомогою Python, який потім розмовляє з DB DB PostgreSQL через ORM (JSON у браузері).

Я також дивлюся на Django, який мені подобається, оскільки його ORM вбудований. Однак я думаю, що Джанго може бути трохи більше, ніж мені справді потрібно (тобто більше функцій, ніж мені насправді потрібно == повільніше?).

Хтось має досвід роботи з різними рішеннями Python ORM, які можуть порівнювати та порівнювати їх функції та функціональність, швидкість, ефективність тощо?


ponyORM виглядає досить приємно.
— Niklas R

Об'єктно-реляційне відображення (ORM) вже дуже популярне в багатьох мовах програмування та одна з найкращих альтернатив для SQL. Мене надихнуло стиль приєднання методів для створення CQL для мого проекту TRIADB. healis.eu/triadb/#latest-release
— Athanassios

Відповіді:


96

SQLAlchemy є більш повнофункціональним і потужним (використовує шаблон DataMapper). Django ORM має чистіший синтаксис і його простіше писати (шаблон ActiveRecord). Я не знаю про відмінності в продуктивності.

SQLAlchemy також має декларативний шар, який приховує певну складність і надає йому синтаксис стилю ActiveRecord, більш подібний до ORM Django.

Я б не переймався тим, що Джанго "занадто важкий". Досить відокремлено, що ви можете використовувати ORM, якщо хочете, не потребуючи імпорту решти .

Це означає, що якщо я вже використовував CherryPy для веб-шару і мені просто потрібна ORM, я, мабуть, обрав би SQLAlchemy.


7
Але якщо вам не подобається ORM Django, і ви хочете використовувати SA, наприклад, ви втрачаєте безліч функцій django, наприклад, адміністратора. Не перерва угоди, а зірване коліно.
— Грегг Лінд

22
Правда, але не має значення для питання, яке стосувалося просто вибору ORM Python; не про автоматично згенеровані адміністраторські інтерфейси чи інші компоненти фрейму
— Карл Мейєр

8
Я б заперечував, що SQLAlchemy - це все, крім легкої ваги - хоча це може бути досить швидким. Я кину свій проект у суміш, він називається peewee, і він розмовляє з postgres. Нещодавно додана підтримка запитів у стилі джанго! charlesleifer.com/docs/peewee
— coleifer

3
Також зверніть увагу, що Django ORM не підтримує складені первинні ключі, а SQLAlchemy підтримує його.
— Марцін Капуста

1
@yegle Мене бентежить ваш коментар. Я не розумію логіки. Як "важко знайти вказівки ORDER BY DESCв документах" означає "поганий для активного шаблону запису"?
— jpmc26

108

Якщо ви шукаєте легку вагу і вже знайомі з деклараційними моделями у стилі джанго, ознайомтеся з 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')

Перевірте документи, щоб отримати більше прикладів.


чи можете ви мені допомогти з цим питанням? Pls ru.stackoverflow.com/q/1114189/293323
— Cookie

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

Слід зазначити, що Storm підтримує MySQL та PostgreSQL лише в поточний момент. Хоча підтримка Oracle працює.
— Джейсон Бейкер

15
Він також підтримує SQLite, як підказує вище приклад
— shearichard

2
quick_orm настільки ж просто, як Storm, і він побудований на SQLAlchemy, тому він також дуже потужний: pypi.python.org/pypi/quick_orm . Відмова: Я є автором quick_orm
— Тайлер Лонг

8
Буря не збереглася. Я б не використовував це для нових проектів.
— Маттіас Урліхс

3
Крім того, здається, що немає шторму для Python 3
— ygormutti

27

Зазвичай я використовую SQLAlchemy . Він досить потужний і, мабуть, найзріліший пітон ORM.

Якщо ви плануєте використовувати CherryPy, ви також можете заглянути в дежаву, як це Роберт Брюер (хлопець, який є нинішнім керівником проекту CherryPy). Я особисто не використовував це, але я знаю деяких людей, які його люблять.

SQLObject трохи простіше використовувати ORM, ніж SQLAlchemy, але він не настільки потужний.

Особисто я б не використовував ORG Django, якщо б не планував написати весь проект у Django, але це тільки я.


SQLObject чудовий - простий у використанні, незалежний від бази даних, і він може насправді робити таблиці для вас! (Я ледачий).
— Лукас Джонс

1
@Lucas - Так може і SQLAlchemy ...
— Джейсон Бейкер

Наскільки я пам'ятаю, я просто загалом робив комплімент SQLObject. Це було дуже давно, хоча ... :)
— Лукас Джонс

@Lucas - я вважав, що такий. Просто подумав, що заноту про це. :-)
— Джейсон Бейкер

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

Але все стає дуже складним, якщо існує багато відносин, таких як one_to_many, many_to_many, наслідування таблиці. Вам потрібно написати багато коду вручну, щоб обробити їх. Перевірте мою відповідь щодо Швидкої ОРМ. Це може заощадити ваш час.
— Тайлер Лонг

18
:) у Тайлер сказав творцю SQLAlchemy, що він повинен використовувати Швидкий ORM.
— Ентоні Бріггс

5
:) Нагадує, що хтось років тому на Usenet сперечався з dmr @ alice, що він насправді не розуміє C.
— Пітер Роуелл,

@AnthonyBriggs, переглянь цей слайд, і ти побачиш, чому quick_orm краще в обробці складних відносин, ніж SQLAlchemy: slideshare.net/tyler4long/quickorm
— Тайлер Лонг

10

Ми використовуємо Elixir поряд із SQLAlchemy, і це до цього часу сподобалось. Elixir наносить шар поверх SQLAlchemy, завдяки чому він більше схожий на лічильники "ActiveRecord pattern".


2
SQLAlchemy підтримує OOP і функціональні стилі поза коробкою, Elixir додає декларативний стиль програмування (в основному для декларацій моделі, але може бути розширений) поверх нього.
— muhuk

5

Це, мабуть, є канонічним орієнтиром для взаємодії баз даних високого рівня в Python: http://wiki.python.org/moin/HigherLevelDatabaseProgramming

Звідси, схоже, Dejavu реалізує схему DataMapper Мартіна Фаулера досить абстрактно в Python.


Я зацікавився і подивився на Деяву. Тільки трохи. Документація дуже рідка (qoute "для шару презентації, який ти маєш"), тому я б сказав лише для досвідчених користувачів.
— r4.

1

Я думаю, ви можете подивитися:

Осінь

Буря


Осінь, ймовірно, легша, ніж Шторм, але Шторм включає багато особливостей, яких осінь не має. Обидва ці варіанти мають обмежену документацію, хоча Шторм так швидко виправляється!
— alecwh

Дякую, Осінь виглядає дуже приємно і привабливо, але має нульову документацію, що є для мене вимикачем угод.
— темпо

1
Я просто спробував деякі приклади на сторінці Осінь, і вони навіть не працюють з версією коду, встановленого мені менеджером пакунків. Дописи групи google також старі. Схоже, проект помирає повільною смертю. Не рекомендував би його використовувати.
— Jason Miesionczek

Шторм, з іншого боку, швидко стає моїм ОРМ вибору. Документи стають все кращими, а API чистий і простий, хоча я трохи більше звик до шаблону ActiveRecord, використовуваного Django ORM, і я вважаю, що Storm легко орієнтуватися.
— Jason Miesionczek

1
Здається, Autum протягом року не проводить жодної активності. groups.google.com/group/autumn-orm
— Шрідхар Ратнакумар

1

Немає можливого способу, що за невикористані функції в Django приведе штрафний показник за продуктивність. Можливо, вам стане в нагоді, якщо ви коли-небудь вирішите підвищити масштабність проекту.


8
є розумний спосіб
— bukzor

0

Я використовував Storm + SQLite для невеликого проекту, і був дуже задоволений ним, поки не додав багатопроцесорну роботу. Спроба використовувати базу даних з декількох процесів призвела до виключення "База даних заблокована". Я перейшов на SQLAlchemy, і той самий код працював без проблем.


7
Справедливості, SQLite насправді не розроблений для одночасного доступу.
— Xiong Chiamiov

2
@Xion +1. SQLITE - це лише один файл, без демона.
— e-satis

-1

SQLAlchemy дуже, дуже потужний. Однак це не є безпечним для ниток, не забудьте це пам’ятати, працюючи з вишневим в режимі пулу з нитками.


2
чи правда, що SQLAlchemy не є безпечною для потоків? Тоді як це використовується в додатках Pyramid через WSGI, які в основному люди розгортають у потоковому режимі? Будь-яке підтвердження цього суперечливого твердження.
— Раві Кумар

1
Звичайно, SQLAlchemy є безпечним для потоків.
— Маттіас Урліхс

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

18
Django не використовує sqlalchemy для свого ORM. Проведено певну роботу, щоб зробити sqlalchemy необов'язковим ORM, але це не є повним.
— шербанг
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.