0,0
рейтинг
9 сентября 2011 в 00:20

Разработка → SQLAlchemy для Django перевод

image Я не люблю Django. Я не люблю Django ORM, Django templates, Django forms и еще множество вещей в Django. Но у Django есть определенное преимущество — многие используют Django, практически любой python-программист знаком с джанго. Поэтому приходится мириться с недостатками этого фреймворка, но никто не мешает облегчать себе жизнь, используя действительно хорошие python библиотеки, например SQLAlchemy.

Что в SQLAlchemy лучше чем в Django ORM? Это главный вопрос, который я слышу от Django guys1, и у меня есть на него ответ — SQLAlchemy может выразить любой SQL запрос (ну 80-90%), в отличие от Django ORM, в котором можно выразить только весьма простые вещи.

И в некоторых Django проектах возникает необходимость в сложных запросах, на которые стандартный ORM неспособен. Условно предположим, что в момент создания проекта считалось, что Django ORM вполне хватит. Для решения можно писать чистый SQL или воспользоваться SQLAlchemy. Я за второй подход, так как чистый SQL плохо поддается DRY-фикации.



Какие недостатки при использовании SQLAlchemy? Нужно описать структуру данных для этой библиотеки отдельно, так как SQLAlchemy и Django ORM не совместимы, да и не было такого плана у их создателей. Также вы можете попробовать построить модель данных по структуре из БД. Тоже вариант, но всплывают тонкие моменты, когда собственно БД еще нет. Я пошел по другому пути и построил структуру по джанго моделям в своем проекте Aldjemy.

Для использования вам просто нужно добавить `aldjemy` в конец INSTALLED_APPS, и aldjemy пройдется по всем моделям и добавит к ним аттрибут `sa`.

Попробуем, запускайте ./manage.py shell_plus и введите:

User.sa.query.join(User.sa.user_groups).join(User.sa.user_groups.property.mapper.class_.group).filter(Group.sa.name=="GROUP_NAME")


Стоп, нужно указывать все join-ы явно? Конечно, это же SQLA, и в SQLA запросы строятся с явным указанием всех join-ов и прочего. Но на самом деле, надо ли использовать SQLA для выборки пользователей в группе? Конечно нет! SQLA придет на помощь в тот момент, когда вы будете писать сложный запрос, направленный на оптимизацию, на ускорение генерации страницы — и здесь возможность написать именно тот запрос, который вам хотелось, будет благословением.

Проект на github.

Или на PyPi:
pip install aldjemy


1. Django guys это такие ребята, которые упорно не желают видеть недостатков Django. Более того — да они даже не в курсе про множество библиотек за пределами этого узкого Dj-мирка.

Из документации: But aldjemy is not positioned as Django ORM drop-in replacement. Its helper for special situations.

Пример кода, который вы так просите habrahabr.ru/blogs/python/128052/#comment_4231276
Перевод: Mikhail Krivushin
Кривушин Михаил @Deepwalker
карма
18,7
рейтинг 0,0
Программист
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое Разработка

Комментарии (303)

  • +14
    Ну по моему не кто не говорил что django orm идеальна, и сами разработчики говорят что они покрывают самые базовые вещи, а всё что за пределами то используйте пожалуйста сырые запросы sql или что либо иное, при этом orm покрывает 90% всех потребностей. Но есть другая проблема, так называемые ваши ребята не видят не только что за пределами, но и то что есть из коробки, большая часть вопросов решается прочтением документации (есть и сеты и F и т.п), а не криками как всё плохо и бежать искать что либо иное. Вопрос в правильном выборе инструмента, и если изначально видно что будет сложная структура, то это уже другой разговор.
    • –7
      Я отлично знаю пределы возможностей Django ORM. Ни фига они не покрывают, достаточно шаг влево, и капут. Все эти примочки типа F, annotate и тому подобное, это костыли к изначально кривой идее. И то, что «сами разработчики» знают об этом, не делает SQLA ненужным. Когда уже запрос стал достаточно сложным, надо брать SQLA.

      Сказать вам что было видно стартующему проект, для которого была сделана Aldjemy, я не берусь. Но думаю он не рассчитывал на некоторые use-case проекта, которые возникли позже.

      В общем «не учите меня жить», будут такие же проблемы возьмете aldjemy и решите.
      • 0
        Может проблема в том, что не надо использовать Django для проектов в которых есть шаги в сторону? Есть прекрасная ниша в которой django рулит и все быстро и красиво получается. А то как начинаешь задумываться о шаблонах, формах, скафолдинга и магии и потом о том как это можно прекрасно все избежать используя что-то другое.

        А то что начинают на Django CRM'ы писать не от большого ума.
        • +4
          Не всегда вначале пути проекта видно, куда он там идет. Джанго берется по привычке и вперед. А выкидывать старый проект из-за некоторой его части, с которой можно в принципе разобраться — зачем?

          А так я полностью согласен на джанго не писать :)
          • 0
            Мне не нравится эта экспедиция, мне не нравятся эти мотросы, и вообще мне ничего не нравится! © м/ф «Остров сокровищ»
            youtu.be/IHui3_d67AU
    • +1
      в 2008-м году начинал писать на django интранетовский сайт для работы именно из-за большого сообщества, когда дело дошло до join-ов, фильтров, связке более двух таблиц код стал пухнуть, как на дрожжах. Вьюхи всех проблем не решают, да и в БД не хотелось лезть. Еще с URL-ами в django перемудрили.
      В итоге переехал на Pylons+SQLAlchemy(ныне Пирамида), по архитектуре, ИМХО, он на порядок лучше и прозрачнее Django.
      • –1
        не знал, что есть «истинные» django-дрочеры, аж карму опустили :)
        • 0
          Не уверен про джанго, а вот нелюбителей пирамиды достаточно.
  • +6
    Никогда не понимал таких статей. Так и хочется крикнуть — Люди! Выбирайте инструмент по задаче!
    • 0
      Надо знать плюсы и минусы инструмента и на основе этих знаний делать выбор. Подобные материалы позволяют узнать недостатки и достоинства, но в большинстве своем они однобоки и практически бесполезны.
      • +1
        Это статья о вполне конкретной вещи, а не сравнительный анализ SQLA и Django ORM — нечего там анализировать.
    • +1
      Есть такая тема, что инструмент могут выбрать задолго до вас. Плюс к тому начать писать на джанго многим легче, чем на SQLA.

      И SQLA инструмент по задаче — есть проблема на старом проекте со сложными запросами — берем SQLA и решаем.
      • +1
        > Есть такая тема, что инструмент могут выбрать задолго до вас.
        А в этом случае статья тем более бессмысленна, т.к. выбор уже сделан и работаешь с тем что дали. Если только для собственного развития.

        > Плюс к тому начать писать на джанго многим легче, чем на SQLA.
        Да и сравнивать Django и SQLAlchemy некорректно.

        Пишем на python, а это все инструменты облегчающие нам жизнь. Ведь можно взять джангу приправить ее алхимией и завернут в джинжа.
        • 0
          >> А в этом случае статья тем более бессмысленна, т.к. выбор уже сделан и работаешь с тем что дали. Если только для собственного развития.

          А вы точно читали статью? Александр, плохо рубить с плеча незнакомый текст, вы хоть ознакомьтесь с ним, чтобы рубить предметно.
          • +2
            Читал и не в коем случае не собираюсь как-то «рубить» или говорить что она не нужна, не вырывайте мои слова из контекста. Я приверженец подхода инструмент под задачу, когда достаточно Django ORM — использую его, когда нужна алхимия — почему бы нет. ORM в принципе штука сомнительная (у меня не такой большой опыт использования алхимии, может она и генерирует хороший SQL). Но вот смотрю я на несколько проектов часть из которых довольно нагруженные и там в основном одни прямые запросы.

            Еще раз, я не к тому что хороша та или иная библиотека (модуль), а к тому что у каждый инструмент решает свою задачу. А в статье есть несколько сомнительных высказываний.

            P.S. Неплохо было бы привести примеры запросов как они выгладят на django orm и с использованием aldjemy, а так же что генерируют обе библиотеки и включить их в статью.
            • +2
              Да не нужно примеров. Когда вам понадобится SQLA, вы об этом точно узнаете. Просто пока она вам не нужна — ну не объяснить. Да, у вас прямые. Это же клево! А у меня уже навороченные и select_related спасать перестал.
            • +1
              Не, если у вас мало опыта работы с SQLAlchemy то пожалуй можете и не догадываться насколько она мощнее. Попробуйте с ней поработать поплотнее — сразу поймете.
              Я не троллю, просто сам под Django разрабатывал, а потом на Pylons занесло. Сам по себе Pylons так себе, но из за SQLAlchemy на Dkango не хочется возвращаться.
              • 0
                А вы можете сравнить SQLAlchemy и Doctrine2 (PHP если что)? Вот мне после знакомства Doctrine2 на любую ORM, реализующую ActiveRecord возвращаться не хочется, даже будь она под Рельсами или Джанго, я лучше на голом пхп писать буду, а уж учитывая наличие symfony2 или, хотя бы, Sylex…
                • 0
                  Я только с Propel работал из пхп-шных год назад последний раз. Но пропель это огромный кодогенератор и я с ним как то не очень подружился. Не понравилось кажется еще что можно одно и то же несколькими способами получить, деталей не помню. Задавать модели XML-ем тоже не нравилось. С Doctrine я не работал.
                • +2
                  Вообще-то, что Doctrine2, что SQLAlchemy реализуют паттерн DataMapper, а не ActiveRecord, как DjangoORM и та же KohanaORM под php.

                  По сути, Doctrine2 — это SQLAlchemy на PHP. Что там сравнивать? :)

                  Если кто не в курсе, фишка DataMapper'а как раз в том, что поля ORM-объекта могут быть откуда угодно (вычисляемые sql-выражения, memcached или лежать на другой машине, с доступом по WebDAV), а не только из базы и при чтении/записи в поля объекта мы можем описать логику чтения/обновления этих данных. ActiveRecord же жестко привязан к записям в таблице.

                  Ну и по моему опыту работы с SQLAlchemy могу сказать, что там очень круто и по-уму реализовали движок sql-выражений. Выдает достаточно оптимизированный код даже на сложных запросах. Крайне редко приходилось прибегать к голому SQL.
                  • 0
                    В общем-то потому и попросил сравнить, что один паттерн реализуют, который дюже нравится :) Интересно сильно ли реализации отличаются, если отбросить языкозависимые штуки. В той же Доктрине не только DataMapper, но и UnitOfWork
                    • 0
                      Кстати, вспомнил за что еще люблю SQLAlchemy — очень удобны в использовании перегруженные операторы — т.е. можно писать например
                      .filter(User.id >= 100)
                      вместо чего-то в стиле
                      User->id->gte(100)
                      Это мелочь, конечно. Но «Дьявол скрывается в деталях»
                    • +2
                      С этим у алхимии все круто:
                      The Unit Of Work system, a central part of SQLAlchemy's Object Relational Mapper (ORM), organizes pending insert/update/delete operations into queues and flushes them all in one batch. To accomplish this it performs a topological «dependency sort» of all modified items in the queue so as to honor inter-row dependencies, and groups redundant statements together where they can sometimes be batched even further. This produces the maxiumum efficiency and transaction safety, and minimizes chances of deadlocks. Modeled after Fowler's «Unit of Work» pattern as well as Hibernate, Java's leading object-relational mapper.

                      www.sqlalchemy.org/features.html

                      Поэтому я и назвал Doctrine2 алхимией под php. :)
                      • 0
                        Спасибо, тогда надо будет попробовать :)
    • –1
      Кстати, забыл совсем. Никогда не понимал вот таких поверхностных комментов от «экспертов».
      • +3
        Если честно не понял кусок про эксперта. Но вы в общем-то рекламируете определенную библиотеку и сравниваете ее с django orm, при этом не приведя ни одного примера использования обоих решений для одной задачи.

        Не любите django? Так не используйте. Не нравится какая-то одна ее часть — замените аналогом, что вы в общем-то пытаетесь сделать, но при этом ваш материал больше похож на рекламный, при том что сравнение было бы куда интересней и полезней.
        • 0
          Да нет же. Я про интеграцию — когда нужно, есть путь как прикрутить SQLA в проект, вот и все. А убеждать в пользе SQLA я никого и не собирался. Просто поделился своим решением.
    • 0
      Иногда переписывать проект во второй раз сложно себя заставить или времени не хватает, вот и вырастают такие франкенштейны, а с первого раза это надо оочень хорошо провести планирование и заморозить на время разработки заказчика.
      • 0
        Это не такой уж франкенштейн, вполне рабочее решение. Генерировать ли модель данных по Django моделям, или брать какую-то обертку для этих целей — такая уж ли это большая разница?
  • +14
    настолько толсто, что аж спорить не хочется.

    оставим за бортом вопрос ускорения генерации страницы с помощью огромного джоина.

    оставим вне рассмотрения странную позицию автора, описываемую фразой «мыши плакали, кололись...» — если из django выборсить самую вкусняшку (я имею в виду модели, с обвязкой из сигналов, пермишнов и т д. а в особенности — админку под всё это из коробки), то она не нужна.

    А вот что хотелось бы узнать у автора, это всерье ли он считает, что

    User.sa.query.join(User.sa.user_groups).join(User.sa.user_groups.property.mapper.class_.group).filter(Group.sa.name==«GROUP_NAME»)

    легче читается и проще поддерживается чем аналогичный sql запрос?
    • +1
      Привычка выкинуть при прочтении половину строк сильно подводит вас.

      > А вот что хотелось бы узнать у автора, это всерье ли он считает, что
      Конечно нет, что видно из текста:
      Но на самом деле, надо ли использовать SQLA для выборки пользователей в группе? Конечно нет!

      Никто не предлагает заменять ORM, я предлагаю решение для сложных случаев.
    • –3
      > оставим за бортом вопрос ускорения генерации страницы с помощью огромного джоина.

      Кстати, а что по вашему делает select_related? Опять «эксперт»?
      • –3
        select_related это костыль.
        • –4
          Эксперт очевидность утверждает, что в реальной жизни разбивка select_related на 2 запроса дает избавление от головной боли и +500 в карму
          • +5
            100%, наивная реализация джойна в вашем «экспертном» коде порвет джойны в БД, которые написали хлюпики-ботаны из CS.
            • +1
              Порвёт на раз, потому что большую часть приджойненых объектов я подтяну из кеша.

              select_related() с явным указанием что джойнить работает отлично.
              • 0
                Я про то и говорю :) просто mjr27 предлагал сделать вместо одного запроса с джойнами запросов по числу нужных моделей. И кеш видимо свой сделать.
    • +1
      Зачем зацикливаться на админке, моделях и т.п. вещах? Да, они облегчают жизнь, но это не панацея, ту же админку, если вам нужно больше предлагаемого функционала — проще и быстрее написать свою.

      Еще раз Django это инструмент облегчающий нам жизнь, коих кстати много, то что он самый распространенный, не делает его лучшим, но отказываться от джанги из-за админки как и выбирать ее из-за этого — имхо глупо.
      • 0
        Отказываться — да, выбирать -нет.
      • +1
        Выбирать джанго из-за админки — не глупо, экономит очень много времени, и даже если она вам не подходит для отдельного приложения или модели, то нужно будет переписать только для них, а для всего остального будет работать стандартная. Да и возможности кастомизации админки джанги весьма велики, так что полностью переписывать возможно и не понадобиться.
        • 0
          Админка у джанги страдает родовой травмой — она начата не с того момента. Хорошие и правильные идеи админки лежат в Svarga.

          Почему — админка джанги заточена на CRUD. Все ее возможности в этой плоскости и располагаются. Админка в Svarga построена без завязки такой жесткой на модели. То есть базово кирпичик Сварго админки начинается с пункта меню. Что за ним будет, список ли моделей, или график загрузки сервера, выбор разработчика. И то и другое вставляется одинаково легко.

          Собственно Bundle я из Svarga во Flask уже портировал, можно и над админкой подумать.
          • 0
            > Собственно Bundle я из Svarga во Flask уже портировал, можно и над админкой подумать.

            Было бы неплохо.
  • +3
    Из чистого любопытства. Привидете, пожалуйста, пример когда это может быть полезно. Если я правильно понимаю пример из статьи, то он стандартным джанговским орм решается примерно так (по памяти)

    class User(models.Model):
    name = models.CharField()
    groups = models.ManyToManyField(Group, through='Membership')

    class Group(models.Model):
    name = models.CharField()
    members = models.ManyToManyField(User, through='Membership')

    class Membership(models.Model):
    user = models.ForeignKey(User)
    group = models.ForeignKey(Group)

    ну и соответсвенно потом можно как и User.groups — список групп, так и Group.members — список участников.

    или я что-то пропустил?
    • –2
      Да, вы пропустили прочесть статью. Статья о том, как ничего не править в проекте, а взять и нафигачить запрос на SQLA без головной боли и без переопределения моделей. Такой вот финт для застарелых проектов, которые переписывать слишком долго.
      • +4
        похоже вы пропустили прочесть мой комметарий. было интересно зачем прикручивать SQLA. на реальном примере. ибо приведенный вами пример очень сильно притянут за уши.
        • –2
          Это пример написания запроса был, если что. А не пример как надо делать. И об этом там же и написано:
          > Но на самом деле, надо ли использовать SQLA для выборки пользователей в группе? Конечно нет!
    • +3
      Вот, что попалось на глаза из текущего проекта:

      return (SettlementLine.query(Settlement, Payment, Order, Event)
              .join(Payment)
              .join((Settlement, SettlementLine.psp_settlement_line_id == Settlement.id))
              .join(Order)
              .join(Event)
              .outerjoin(IdsLine)
              .outerjoin(IdsBatch)
              .filter((SettlementLine.batch == None) &
                      (SettlementLine.settle_after < datetime.now()) &
                      (SettlementLine.source == SettlementLine.Source.ECOMMERCE) &
                      ((Order.domain_id == Route.domain_id) |
                       (IdsBatch.status == IdsBatch.State.RECEIVED)))
              .all())
      

      • 0
        надо бы еще на можели взглянуть, но на вскидку

        qs = SettlementLine.filter(batch=None).filter(settle_after < datetime.now).filter(SettlementLine.source=SettlementLine.Source.ECOMMERCE))

        result = qs.get( Q(order_domain_id=Rout.domain_id) | Q(idsbatch.status = idsbatch.state.RECEIVED) )


        не уверен насчет последнего Q объекта, просто не понял логику связи. но как то так.
        • 0
          «SettlementLine.query(Settlement, Payment, Order, Event)» вытаскивает 5 объектов в каждой строке. Типа, «for settleline, settle, payment, order, event in thisquery» было бы.
          • 0
            джанго вытащит их ленивыми. ну или select_related поставить впереди. это при условии наличия связей между моделями, конечно.
            • 0
              Ленивыми == не вытащит. select_related работает только для прямых запросов. И разве ему можно уже указать «этого тащи, этого не тащи»?

              Бтв, IdsBatch — он через Order, Event, IdsLine, IdsBatch. Так что это будет что-то типа Q(order__event__idslines__idsbatches__status = RECEIVED). Я уже умудрился забыть, обратный джойн в джанге работает?
              • 0
                с чего вдруг ленивыми == не вытащит? вытиащи но у вас будет пеформанс хит при обращении.

                >И разве ему можно уже указать «этого тащи, этого не тащи»?

                таки да.

                >Q(order__event__idslines__idsbatches__status = RECEIVED). Я уже умудрился забыть, обратный джойн в джанге работает?

                все равно это проще чем та кверя, что привели вы. обратный джойн работает, да
                • +1
                  > с чего вдруг ленивыми == не вытащит? вытиащи но у вас будет пеформанс хит при обращении.

                  Не вытащит — в плане они не будут у меня, это будет еще один запрос (ну, не один, десяток).

                  > все равно это проще чем та кверя, что привели вы. обратный джойн работает, да

                  Да не, не проще. Особенно учитывая, что у меня в ipython'e автодополнение для алхимии работает, а для джанги, очевидно — нет (кто ж дополнит order__event__idslines?). Энивей, я просто навскидку что-то вытащил из кода, и не подбирал специально что-то феерическое.
                  • +4
                    вы эта, критерии сразу озвучивайте. а то получается:
                    — джанговскийо орм гавно, вот так он не может…
                    — да, гавно конечно, но может…
                    — неее, так не считается. это на ipython не сработает.

                    давайте сюда еще мобильные дивайся притянем, загоним сразу несколько бд в проект и начнем сравнивать.

                    Повторюсь. ни у кого не вызывало сомнений, что алхимия более функциональна, был интересен конкретный пример, с чем автор столкнулся. автор сначала натурально быковал (ну потом он конечно назвал это тема стайл экспресиия) потом привел мутную алхимеческую кверю, без описания моделей, которая использует внутри себя другие врядли менее мутные квери и ходит довольный. рассказывает какой он весь в белом втихую глумится над «экспертами».

                    Нормальный ответ был бы. бизнес кей такойто- надо сделать вот такуюто выборку, по таким то критериям, обязательно вот в такой временной промежуток, ленивость нежелательна, должно работать на таких, то бд, потому что продакшен одна бд, для тестов юзаем другую. не надо кверей. просто описание кейса.

                    всё. граждане бы посмотрели, поцокали языком, примерили бы на свои проекты, поломали бы голову, а можно ли как то извратится и забабахать это на стандартной джанге (просто голову размять) и было бы интересно и полезно.

                    а так, получилась помойка с минимумом конструктива. причем автор считает, что он душка-зайка, никому не хамит, а это его «эксперты» одолевают :)
                    • 0
                      Что такое? Я сразу сказал, что одним запросом из джанго-орма не вытащить. У тебя будет по 5 (минимально) запросов на каждый SettlementLine, что ты обрабатываешь. Учитывая то, что я достаю их по 100 штук обычно, выходит 501 запрос. Всë, нашему приложению жопа.

                      Так что говно и не может.
                      • 0
                        Давайте может на конкретных примерах :)
                        Не ради померятся размерами, а ради чисто профессионально интереса)

                        Можете сделать запрос, достаточно сложный на sqla и вывести raw запрос который он формирует.

                        Я постараюсь сделать на джанго тоже самое — посмотреть насколько хуже оно там получается.

                        Интерес не ради «померяться», думаю это многим будет интересно )

                        • 0
                          Я уже показал три запроса, все три достаточно весëлые. Но у меня плохо сейчас со временем, я последние часы дорабатываю на текущей работе, так что сорри, нет времени меряться серьëзнее.
                      • 0
                        гдето изначально речь шла про количество запросов? вроде говорили про возможность выразить тот или иной селект через 2 разных орм.

                        ну и ненадо гонять коня по вакууму. если хочется конструктива, берем конкретный кейс. типа вот модели, вот такой сценарий. и тут можно думать и обсуждать как это сделать на джданге как на алхимии. зададим критерии крутости. и тогда можно будет говорить что говно а что нет.

                        ну и само по себе сравнение чуть странновато, джанго она ближе к DDD и его принципы старается использовать, а алхимия идет от структуры базы.
                        • +1
                          Критерии крутости — я на алхимии могу сделать и оно работает, а на джанге у меня не хватает времени всë обработать, приходится скатываться в raw sql, чего я абсолютно не хочу.

                          По-моему, это очевидный критерий.
                          • +1
                            нет, не очевидный. я на джанге на ро сиквеле сделаю так что работать оно будет на 40% быстрее и сожрет на 20% меньше памяти на каждый запрос, разработка займет в 2 раза меньше времени, новый человек разберется за 15 минут вместо 2х часов. (для *конкретного* кейса)

                            вот это я понимаю — критерии.

                            на всякий случай: это ирония.
                            • +1
                              Ну, серьëзно, неужели возникает ощущение, что я сижу и мечтаю переписать какой-то ужасный запрос на raw sql и весь код, который его юзает, измерить время, потом на джангу, и т.д.? Конечно, инструмент для задачи. У меня в задачах — сложное приложение со сложными запросами. Мне надо вытащить кучу данных и потом с ними дальше работать удобно. А в одном месте замутить raw sql, и дальше у тебя не объекты, а словарики и списки. Не очень приятно.

                              Если кажется, что джанговского орма хватает — я не против. Мне так тоже раньше казалось, и мне хватало, но иногда приложения бывают сложнее, а иногда проще.
                              • +1
                                джанги давно уже не хватает, есть масса решений в том числе и для подключения алхимии. наш профессионал только недавно до этого дозрел, видимо.

                                просто вопрос изначально стоял в другом. профессионал написал, что джанго-орм гавно привел пример подтверждающий обратное и самже в нем усомнился.

                                с таким подходом к вопросу мне стало интересно как оно у профессионала в реальной жизни. лично мне. за других не знаю. просто лично у меня, когда созрела проблема с джангой мы от нее отказались. просто опыт подсказывает, что предложенное профессионалом решение — временное. это только первая проблема в которую он уперся. причем эта проблема давно обсуждалась в непрофессиональных, интеллектуальных кругах (где уж нам).

                                собственно мои вопросы были из любопытсва понять с чем столкнулся профессионал и сравнить с тем с чем когда то столкнулись мы.
                                • 0
                                  Усомнился?
                                  • 0
                                    в чем?
                                    • 0
                                      > написал, что джанго-орм гавно привел пример подтверждающий обратное и самже в нем усомнился.

                                      Я усомнился в примере? Пример мозг не взрывает, я не искал специально, но тем не менее это 1 запрос, а не много.
                                      • 0
                                        Он имел в виду пример из топика. Я в нем не сомневался, просто отметил что в этом случае SQLA нафиг не нужен.
                                        • 0
                                          А, ок. Он просто начал разговаривать странным слогом и я потерялся в профессионалах.
                                          • 0
                                            там просто чуть ниже автор себя причислил к профессионалам, а всех остальных к «экспертам». Так что я исключительно ради соблюдения этикета, вдруг обижу человека
                                      • 0
                                        речь шла про автора. автор усомнился в приведенном в статье примере.
                                        • 0
                                          Но он не усомнился. Он просто сказал, что вот так можно делать запросы. База, типа, чтоб было понятно, куда смотреть.
                                          • 0
                                            /*Стоп, нужно указывать все join-ы явно? Конечно, это же SQLA, и в SQLA запросы строятся с явным указанием всех join-ов и прочего. Но на самом деле, надо ли использовать SQLA для выборки пользователей в группе? Конечно нет!*/

                                            тоесть так делать можно, но, конечно, не стоит. это и означает сомнение в примере. и захотелось посмотреть на реальную ситуацию
                                            • 0
                                              Никакого сомнения. Пример с потолка, просто демонстрация того как выглядит запрос в SQLA. Да еще и отличное предостережение, что не надо микроскопом гвозди то заколачивать.

                                              Вы сами то приведите хороший пример. Это сложно достаточно сделать, вырвать из контекста и тому подобное. Поэтому и берется простой дубовый пример с дисклеймером.
                                • –1
                                  С чего и надо было начинать.

                                  Нет, с джанго и ее проблемами я знаком очень давно. Алхимию наш профессионал использует также с успехом продолжительное время и умеет ее готовить.

                                  А с проблемой я столкнулся простой — нужна сложная выборка, которую в итоге написали на raw sql. Получилось неплохо, все работает, но во-первых только на одной БД, а во-вторых вносить в эти запросы изменения адский ад.

                                  От джанго я давно и с успехом отказался везде, где это возможно. Но уже неоднократно здесь указывалось, что отказаться от нее в старом проекте практически невозможно, особенно учитывая большой поток feature запросов от заказчика. А так я предпочел бы не пинать труп, и забить на джангу в комплексе.
                    • –2
                      Автор считает, что никому не обязан представлять никакие юзе кейсы, достаточно идеи и рабочего кода.

                      Имею право послать всех «экспертов» которые думают иначе.
                      • 0
                        да да да. только я знаю истину и несу ее свет! вы «эксперты» еще не доросли до моего величия, поэтому я вас посылаю!

                        кхм, извините, нимб не жмет?
                        • –2
                          «эксперты» явно не доросли. Те, которые доросли, юзе кейсы не просят, они сами все знают. Они себе добавили ссылочку в закладки, и применят aldjemy в подходящем проекте.
                          А ради товарищей, которые хотят чтобы им значит пояснили предметно, разжевали и в рот положили, напрягаться не вижу никакого смысла. Я таких товарищей не люблю принципиально.
                          Поэтому я вижу идеальный случай этого топика среди профессионалов так — пост, и вопросы в комментах про особенности реализации. И типа почему сделано так, а не так? Может еще предложение полезное.
                          А то что я вижу это унылый троллинг от интеллектуалов (сарказм).
                          • 0
                            судя по всему, не жмет. клёва.
                          • +1
                            Поэтому я вижу идеальный случай этого топика среди профессионалов так — пост, и вопросы в комментах про особенности реализации. И типа почему сделано так, а не так?


                            Ну давай попробуем :-)

                            1. Реюз Django connection в пуле — прикольно :-)
                            2. Тесты, тесты. Хочу тесты, хотя бы простые, а то возникает много вопросов «M:M работает? Наследованные таблицы работают?».
                            3. В целом, прикольная библиотека, в плане «полезной зарядки для ума» :-)
                            • 0
                              Реюз коннекта это кстати Владимир Михайленко сделал, за что ему спасибо огромное. Я же стартанул свою библиотеку от его интеграции SQLA в проект, и увел ее в сторону генерации модели данных по Django моделям.

                              Тесты, да. Обычно я начинаю библиотеки с тестов. У этой они тоже есть, но лежат в секретном проекте. Придется написать отдельные, раз уж библиотека пошла в мир.
  • +5
    Питонщики нынче, судя по комментариям, с ядовитыми железами пошли…
    • 0
      Да ну тут как почитаешь «экспертов» в комментариях, которые SQLAlchemy в глаза не видели и требуют от меня доказать что оно лучше, так пожалуй коброй станешь.
      • 0
        так приведи пример-сравнение. многим сразу стало бы понятнее насколько sqla мощнее и гибче django orm :)
        • 0
          Просто примеры выдирать из кода — ну там же не понятно будет что к чему. Придумать из головы — ну никто же не скажет «о, круто», скажут «а нафиг тут так сложно»? Несмотря на искусственность примера. Поэтому было желание к этому не скатываться, тем более что не о том статья.

          Вот пример, но это именно вариант «ни фига не понятно зачем оно так»:

          habrahabr.ru/blogs/python/128052/#comment_4231276

          PS Не тыкайте. Это лично ваш выбор, беседовать на ты, он не обязан быть приятен собеседнику.
          • +1
            без примеров это вызвало не меньше вопросов, чем с хоть какими то примерами.

            PS Вы можете просто не отвечать.
            • 0
              Почему же не отвечать, я же топик написал, чтобы развеяться за приятной беседой с умными людьми. Как выяснилось их много, даже чересчур. А в общем именно на это я и рассчитывал, я же знаю хабр и его уровень.

              С примерами все идет не в то русло, начинаются какие-то странные предложения как решить проблему иначе — и все они сильно хуже и не решают поставленной задачи. На мой взгляд результат один — разговоры ни о чем.
              • 0
                я задаю вам вопросы не для того чтобы доказать что дж.орм крут или алчеми отстой.
                Я иногда сталкиваюсь с ситуациями, как и многие, когда нужно более-менее юзабельно формировать\компоновать\собирать raw запросы.

                Как вариант решения — параметризованные функции или классы обертки которые становятся более-менее универсальными и цельным объектами в коде.

                Я так понимаю, sqla как раз решает эту задачу. И мне конечно было интересно увидеть примеры и т.д.

                Но я уже пожалел о том, что начал тут что-либо писать и спрашивать)

                • 0
                  Вообще первые комменты как всегда пошли в русли «а чо а нафиг, а докажите мне что оно мне же нужно». Ну вот в этом русле и пошло. Были бы другие вопросы, были бы другие ответы.

                  Да, я понимаю, что было бы интересно. Парочку привели в комментах, на большее рассчитывать не стоит, у всех своих дел хватает.
                  • 0
                    Если ты людям что-то предлагаешь, то должен объяснить зачем им это и чем это лучше того, что у них есть. По-моему, очевидная вещь.
                    • 0
                      Вот как раз нет, ничем я людям не обязан. По-моему готовой реализации уже выше крыши для людей. Если я не хочу объяснять и спорить, имею право. Ведь объяснениями не заканчивается — начинается поток экспертных мнений, по типу джойны руками на стороне бека сделать. Поэтому лезть в этот шит очень не хотелось, но не удалось отбиться малой кровью.
                      Основной мотив вопрошающих это найти какой-нибудь изъян по их мнению в логике и накинуться с криками «ЫЫЫ, абырвалг, мы лучше знаем, джойны отстой».
  • 0
    Если у сабжа честный DataMapper то обеим руками за. Это надо почувствовать, что такое когда твои модели зависят только друг от друга!!!
  • +5
    Ура! наконец люди начали смотреть на вещи трезво.

    Кстати, есть еще одна реализация lucumr.pocoo.org/2011/7/19/sqlachemy-and-you/ от Армина Ронашера.
    Здорово то, что людей с пугавицами вместо глаз(читай Django gays) становится меньше. И многие начинают понимать, что за пределами django есть огромный мир интресных и мощных инструментов! И что python не начинается и не заканчивается на джанго. Не стану отрицать, django — гениальная вещь, в свое время ставшая революцией. Люди до сих пор плачут от счастья, переходя с PHP на python/django, но(!). Трудно остановить прогресс и пыливую мысль программиста, желающего упростить свой труд =) Теперь есть инструменты более мощные, гибкие, при этом намного менее ограниченные чем django.
    К примеру, я сейчас использую:
    — flask
    — wtforms
    — mongoDB
    — mongoalchemy
    — flask-mongo-admin.
    и не испытываю дискомфорта от того что что то не получается реализовать.

    И считаю себя счастливым человеком =)
    • +2
      +1.
      мой инструментарий:
      — cherrypy
      — wtforms
      — python-mysqldb
      — jinja2
      — sqlalchemy
    • НЛО прилетело и опубликовало эту надпись здесь
      • +1
        > flask-mongo-admin? почему-то не гуглится
        Написан мной, его нет в открытом доступе. Подготовлю версию, но чуть позже, если кому интересно =)
        • НЛО прилетело и опубликовало эту надпись здесь
          • 0
            Просто редактор содержимого базы. Регистрируешь модели и все. Сделан на основе wtfrms. Нет ровно никаких украшательств, которые есть в джанго админке. Просто. Работает.
            =)
        • 0
          Строите формы по моделям mongoalchemy? Вложенные структуры поддерживаются?
          • 0
            1. Да.
            2. Нет.
            Выводится json в textarea, и редактируется там. Планирую с ним сделать json редактор на клиенте. Наброски уже имеются.

            + еще добавил автоинкремент и свойство id к любому документу. По ним и шерстит админка.
            • +2
              Просто у меня еще одна библиотечка есть в процессе допиливания github.com/Deepwalker/procrustes
              Работает со вложенными структурами.
              • 0
                Это интересно!
    • +3
      Django gays???
    • +2
      Это не реализация, это рассказ как переехать на SQLA с джанго. А у меня библиотека, которая дает легкий путь к генерации SQLA запросов.
      • 0
        • 0
          не, это совсем не то… По ссылке штука, которая позволяет в SQLAlchemy делать filter_by(entries__headline__exact='b2 headline 2'). В статье все как раз наоборот.
        • 0
          Сорри, это Ваша библиотека, наоборот )
  • 0
    Маны читать не пробовали?
    Performing raw SQL queries
    Complex lookups with Q objects
    • НЛО прилетело и опубликовало эту надпись здесь
      • 0
        > Когда ORM скатывается в raw SQL это очевидным образом fail, вам так не кажется?

        почему?

        орм пытаются быть универсальными, универсальность, обычно, накладывает ограничения, как по перфомансу, так и по функционалу. Если у орм есть вменяемый маппер, который сможет замапить результат голой сиквел квери в объекты, то что кроме религии, мешает это использовать? особенно учитывая, что все эти тонкости реализации остаются внутри репозитория, а наверх отдаются только объекты.
        • –2
          Да потому что сырой SQL практически невозможно написать так, чтобы можно было следовать DRY. Пока вы это будете делать — нафигачите еще одну либу.
          • +1
            я так понимаю примеров подтверждающих ваши утверждения можно не ждать :)
            особенно в сопоставлении вместе с SQLA, ну как там аналогичный пример решается с соблюдением DRY.
      • 0
        Вы не читали ман, ссылку на который я дал. «Raw queries» и «Custom SQL» — разные вещи.
        • 0
          Ну конечно, прочитать ман по sqlalchemy я осилил, а вот по джанго нет. Вы точно так считаете?
    • 0
      Бал «экспертов» продолжается? Ну тоже значит рекомендую к прочтению www.sqlalchemy.org/docs/
      • +1
        Вообще-то я аргументировал неспособность автора адекватно оценить способности Django, которые он уверенно опустил.
        Что в SQLAlchemy лучше чем в Django ORM? Это главный вопрос, который я слышу от Django guys1, и у меня есть на него ответ — SQLAlchemy может выразить любой SQL запрос (ну 80-90%), в отличие от Django ORM, в котором можно выразить только весьма простые вещи.

        Так что причем тут ваш комментарий — мне непонятно.
        • 0
          Так я их совершенно по делу опустил. Это понимают все здравые люди, кроме «экспертов».
      • +1
        Скажите, почему вы как эксперт без кавычек с мировым именем, не можете привести пример, подтверждающий необходимость того, о чем вы говорите.

        Пример который вы привели в статье уже был опровергнут. на большее мирового имени не хватает?
        • –1
          Эксперт-нечитаютопики, я этот пример сам опустил в той самой статье, которую вы не читали. Сравнение Django ORM и SQLAlchemy проведите для себя сами, мне это ненужно. Вам нужно, вы и делайте себе сравнительный анализ. Когда я решу написать статью «почему джанго орм сливает sqla», я ее так и озаглавлю.
          • +12
            Ага, краткий персказ обсуждение:

            Автор: Чуваки, смотрите к джанго можно прикрутить SQLA!!! потому что джанговский орм на многое не способен! и теперь вы можете выбирать мембершим вот так: User.sa.query.join(User.sa.user_groups).join(User.sa.user_groups.property.mapper.class_.group) и это клева чуваки, истину говорю вам.

            Чуваки: Ну ок, джанговский говно. но на нем мы мембершип выбираем вот так Group.members. Есть реальный пример когда SQLA будет полезнее?

            Автор: Да вы «эксперты» статью почитайте! там про то что можно в джанго орм заменить на SQLA! а не про то зачем это. просто можно и все. и это круто!

            Чуваки: да понятно, что можно. а зачем? ну реально приведи пример где джанговский будет хуже по какому то критерию.

            Автор: Достали «экперты»! сравнивайте сами, я просто написал что можно. Нужны примерны — сами ищите. когда дорастете и поумнеете сами все поймете!

            Чуваки: ок.
            • +2
              Я привëл пару примеров, когда джанговский орм не годится, можешь поискать по комментариям и посмотреть.
            • 0
              «Чуваки» заменить на «эксперты которые не в курсе что такое SQLAlechmy и считают что автор должен им это пояснить». А я не считаю, что мне нужно вам это пояснять, для этого есть документация, ссылка на которую есть в этом топике.
              Тем не менее спасибо Александру за примеры.

              У меня есть пример, но он очень большой, могу дать маленький кусочек.
                  def q_on_time(self):
                      return self.make_query(
                              self.lproject_and_taskhistory_join,
                              (self.taskhistory_filters_statuses + self.task_not_canceled +
                               self.date_filter(Task.sa.completion_completed)),
                              (Task.sa.delivered_on_time, Task.sa.id)
                      ).group_by(Task.sa.id).\
                      add_columns( (Task.sa.delivered_on_time == 1).label('delivered') ).\
                      from_self().group_by(*self.grouper).\
                      add_columns(
                          (func.sum(expression.column('delivered')) / func.count(Task.sa.id)).label('on_time') 
                      )
              


              Если оно вам поможет, пожалуйста. Если учесть, что это одна из 10 составляющих запроса, то как это выразить на Django ORM я вообще не знаю. Оно там в итоге еще и джойнится.
              • 0
                Уважаемый автор, а теперь попробуйте откинуть ваш апломб, и сказать как вот тут соблюдается DRY и как сильно вот это отличается от голой сиквельной квери.
                • 0
                  А я скажу, без всякого апломба — этот кусочек служит для генерации 9 разных запросов.
                  • 0
                    тоесть меняем скл кверю на хранимую процедуру и проблема чудесным образом решается?
                    • –2
                      Да, и работает на всех БД, что характерно для хранимых процедур. Это магия «эспертов», у них все работает.
                      • +1
                        тоесть у вас такой непростой проект, что вам то орм надо поменять, то базу? :)
                        • +1
                          Тесты на sqlite быстрее бегают.
                        • 0
                          Ну и можно увидеть пример хранимки, которая сделает то же, что и приведенный кусок?
                          • 0
                            примера не будет. я не готов либо переписвать ваш, либо придумывать какото свой который достоточно точно отразит проблему, чтобы вы не сказали потмо что эксперты опять чтото не поняли и все упростили.

                            сама возможность реализации в чем то вызывает сомнения?
                            • –3
                              Да, вызывает сомнения.
                • 0
                  Обратите внимание на код, параметры к self.make_query, параметр self.grouper и тп.
                  • –1
                    то что код возвращает кверисет это очевидно. спасибо, кэп
                    • +3
                      Параметризованный запрос оно возвращает. То есть этот запрос, в зависимости от параметров, хорошо изменяется, и этой гибкости хватает на создание 9 весьма разных запросов. Получить это с raw sql у вас не выйдет, напишете реального франкенштейна.
    • 0
      raw SQL это однозначный костыль, который без оговорок усложняет поддерживаемость, поиск дефектов, внесение изменения в модель, плюс почти что исключает возможность наличие разных версий модели, если кратко, то это дырка в уровне абстракции.

      Каждое из его использований нужно особо выделять в документации и коде и при внесении любых изменений в модель просматривать все raw SQL соответствующего модуля.

      Не просто так его нужно избегать всеми способами, пусть даже ценой большого оверхеда из-за неоптимальных запросов или наличия полей модели с промежуточными результатами каких ни будь вычислений, что вносит избыточность в архитектуру приложения.

      Если raw sql действительно неизбежен и вносится в код раньше заключительных этапов разработки, когда идет работа над увеличением производительности, то стоит начать думать о других инструментах.
  • +7
    Примеры сложных (и нужных, не сентетических) запросов нереализуемых с Django ORM, но реализуемых на SQLA в студию, пожалуйста.
    • +2
      В гугл, пожалуйста, за несентетическими запросами. А эта статья на о сравнении Django ORM и SQLAlchemy. Это для тех, кто это и так знает.
    • +5
      Take it, take it!

      return (order_models.Order.query(order_models.OrderLine, product_models.Product, v1, event_models.Event, rm.TicketwareUser)
              .join(order_models.OrderLine)
              .join((event_models.Event, event_models.Event.id == order_models.OrderLine.event_id))
              .join((product_models.Product, product_models.Product.id == order_models.OrderLine.product_id))
              .join((_Value, _Value.instance_id == order_models.Order.id))
              .join((_Field, _Field.id == _Value.field_id))
              .join((v1, v1.instance_id == order_models.Order.id)).join((f1, f1.id == v1.field_id))
              .join((v2, v2.instance_id == order_models.Order.id)).join((f2, f2.id == v2.field_id))
              .join((rm.TicketwareUser, rm.TicketwareUser.id == v2.value))
              .filter((_Value.value == prog_id) &
                      (_Field.name == 'prog_id') &
                      (f1.name == 'pay_method') &
                      (f2.name == 'user_id') &
                      (order_models.Order.created > last_z))
              .order_by(order_models.Order.created)
              .all())
      
  • +11
    >Я не люблю Django. Я не люблю Django ORM, Django templates, Django forms и еще множество вещей в Django.

    Зачем же автор тогда пользуется этим инструментом? Странный человек.

    В мире python много хороших инструментов — темплейт-энжины, orm-инструменты, микрофреймворки и т.д.
    И «джанго-гайс» думаю прекрасно знают о их существовании. Но это же совсем не означает что разработчики джанго должны их использовать.

    Они сделали свою реализацию ORM — и сделали достаточно неплохо, простой и понятный, подходящий для многих основных задач. Не думаю что они отрицают крутизну sqla, но это совсем не означает что они должны были его использовать в джанго. И называть их слепыми — как то неблагодарно, не под пыткой же вас заставляют работать с джанго.

    Лично мне ORM нравится — я понимаю что он может, что нет. Для большинства моих задач он подходит. Для критичных и сложных случаев — использую raw-запросы, по моему это оптимально. Мне кажется я не один такой — это и есть подбор инструмента по задачам. И джанго позволяет это сделать.

    • 0
      Читаем статью:

      > И в некоторых Django проектах возникает необходимость в сложных запросах, на которые стандартный
      > ORM неспособен. Условно предположим, что в момент создания проекта считалось, что Django ORM вполне хватит.

      Мне кажется, что данная строка отвечает на вашу эскападу полностью. Вопрос, почему вы не прочитали статью, оставим за кадром, селяви и хаброэксперты на марше.
      • +2
        Ты б определился уже, а то в одном месте ты говоришь, что статья про то что можно орм поменять, а не про то что джанговский говно, в другом уже соглашаешься что стратья и про говно тоже. и главное везде хабраэксперты.

        перефразируя известную фразу — что хорошо с «хабраэкспертом», так это то, что «хабраэксперт» это всегда не ты.
        • 0
          Ну блин. Статья о том, как ничего не меняя заюзать мощь SQLA в старом проекте. Что тут сложного то? Ничего не надо выкидывать, ничего не надо переделывать. Просто вместо костылей Dajngo ORM используем SQLA.
          • +1
            вроде никто изначально не спорил чтонельзя можно. на стековерфлоу эта тема обсуждалась года 2 назад, съели и переварили.

            интересна была именно мотивация — зачем.

            При очевидных недостатках джанги правило парето она соблюдает, если вы попали в оставшиеся 20, то, вероятно, джанга не для вас.

            Вы в начале заметили, что джангу выбрали до вас, ну вот окружающим ( в частности мне) было интерсно в чем проблема и критерии ее оценки.

            Вместо того чтоб просто написать было вот так, был геморой, переключили на алхимию и сделали вот так и получилось круто. вы, извините, впали в неадекват и начали рассказывтаь про то какие хабраэксперты плохие.

            таково мое восприятие.
            • +1
              Мое восприятие сильно отличается от вашего, что впрочем с точки зрения философии вполне себе адекватно.
              Зачем — трудозатраты на написание этой библиотеки были сильно ниже, чем переписка всего проекта ради его десятой части.
        • 0
          И тыкать незнакомым людям моветон.
          • 0
            крайне удивительно это слушать от человека, который незадумываясь хамил куче незнакомых людей :)
            • 0
              Где же я хамил? Я рассказываю людям о моем восприятии их комментариев, используя исключительно уважительную форму «вы». Проверьте везде, и попробуйте найти хоть одно место, где я скатился на тыкание.
      • +3
        я прочитал статью.

        Никто не спорит что sqla можно использовать в джанго.
        Вопрос — настолько ли это лучше, насколько утверждаете вы.

        Например, я создал нужные мне модели и использую тесно завязанный с ними ORM. С помощью этого набора я быстро решил 90% поставленных задач. Допустим осталось еще 10%, которые ORM сделать не может (например, нужна производительность, сложный-сложный джойн или что-то еще).
        Тут вы предлагаете использовать sqla и использовать синтаксис вроде этого:

        items = (GuestListEntry.query(GuestListEntryDispatch, EticketDownloadHistory)
        .outerjoin(GuestListEntryDispatch)
        .join((Order, (Order.client_id == GuestListEntry.id) &
        (Order.is_guest == True)))
        .outerjoin(EticketDownloadHistory)
        .filter(GuestListEntry.batch_id == batch.id)
        .all())


        вместо того чтобы написать свой raw-селект.

        В чем же в данном случае преимущество sqla перед селектом? ведь ни то ни другое уже не дадут автоматической привязки к моделям Джанги. А если этого нет, я выберу raw — так по возможностям он все же более надежен и гибок чем sqla.

        Если вы профессионал sqla и умеете его хорошо готовить, возможно Джанго вам и не нужен. Но ведь это не значит что разработчики джанги слепы, а сам фреймворк — какашка.
        • +2
          Отличие SQLAlchemy-вского запроса от raw SQL в первую очередь в том что он отработает на любой поддерживаемой БД (Postgres, SQLite), во вторых, что запрос можно конструировать по частям: эта функция добавит пару WHERE условий, эта что-нить приджойнит, эта добавит новое вычисляемое поле, эта добавит проверку что у юзера есть права на доступ к этому объекту и т.п.
          • 0
            Да, я примерно представил возможности sqla. Я думаю многое из того что вы сказали несложно реализовать в django (и его ORM).

            Я уверен что sqla мощнее и гибче чем django ORM, но думаю в подавляющем большинстве случаев нет необходимости заменять на него встроенный ORM.
            • 0
              Именно. В подавляющем числе случаев не надо SQLA тащить. Я изо всех сил всегда стараюсь за ОРМ не выпрыгивать. Так проект сопровождать легче.
              Но бывает иногда, что лучше взять SQLA, чем городить костыли.
        • –1
          Ну насчет аспектов джанго можно поспорить. Приезжайте в октябре на pyconua — обсудим предметно, перемоем все косточки Django и всем остальным проектам.
          А так да — я считаю, что джанго какашка, и делать на ней новый проект не стоит.

          Про маппинг — можно было бы замаппить таблицы SQLA прямо на модели джанго, мой знакомый разработчик так и делал. Я решил не идти этим путем, потому что возможны проблемы от такого подхода. Впрочем есть пространство для размышлений — у него из запроса выплывали джанго модели, что возможно удобно. Просто в том куске, над которым думал я, модели собственно были не нужны. А потому aldjemy и не выкидывает джанго модели.
          • 0
            >>>я считаю, что джанго какашка, и делать на ней новый проект не стоит

            Чтож, это ваше мнение — у меня нет причин с вами это обсуждать :)

            По моему, если возникла необходимость прикручивать к джанге sqla — то возможно стоило использовать пайлонс либо какой-нибудь из множества других замечательных фреймворков, из коробки поддерживающих и ориентированных на sqla.
            • 0
              *facepalm* постановка задачи обратная.
              • 0
                что за постановка задачи
                • 0
                  Уже есть проект, в нем хренова тонна строк кода, и он на джанго. Переписать?
                  • 0
                    Я не могу ответить вам ни да ни нет, не зная что конкретно вы не стали реализовывать на django ORM + raw. Если вы приведете примеры из реального проекта — тогда думаю мы все сможем оценить масштабы озвученной проблемы )

                    Если серьезно — может есть возможность описать\выложить те задачи которые вы решили не делать на django orm? было бы интересно многим я думаю.
                    • –1
                      Я и без вас их могу оценить прекрасно. Более того, я это сделал еще до первой строчки aldjemy, и пару разу перепроверил, что джанго орм мне точно ничем не поможет. И raw sql тоже.

                      Выкладывать задачи не буду. Можно удовлетворить свой интерес за разработкой своего проекта. А проекты с тонной кода как бы не для общего обозрения обычно, и с NDA.
                      • 0
                        грубый вы) я знаю что вы и без меня можете, как и я без вас, и многие другие на этом сайте.

                        • 0
                          А что делать. Устаешь от подобных вбросов.
            • НЛО прилетело и опубликовало эту надпись здесь
              • +1
                Да. Врагу надо ASP.NET желать :)
              • 0
                У нас сейчас проекты на Pylons разрабатываются… Да, сам Pylons так себе, не все продумано, многих вещей нет, но за SQLAlchemy готов разрабатывать и на нем.
                • 0
                  Но SQLA можно же где угодно использовать. Можно любой фреймворк взять. Мне вот всегда импонировал Svarga, но вроде решили перенести из него полезное во Flask, и не разводить зоопарк. В принципе я того же мнения, но жалко :) Он мне нравился.
          • 0
            А что, если не джа? Пилоны еще веселей имхо.
            • 0
              Речь о legacy.
              • 0
                Строить веб с нуля? Жестоко. Ну или слишком много времени свободного.
                • 0
                  Вы точно с этого топика? Комментарии как-то не в тему сильно.
                  Речь идет об интеграции SQLA в существующий проект, который не надо переписывать.
                  • +1
                    Гм.
                    Deepwalker> А так да — я считаю, что джанго какашка, и делать на ней новый проект не стоит.
                    datacompboy> А что, если не джа?
                    Deepwalker> Речь о legacy.
                    datacompboy> Строить веб с нуля? Жестоко.
                    Deepwalker> Комментарии как-то не в тему сильно.
                    Не понимаю.
            • 0
              flask
  • 0
    https://www.pylonsproject.org/ каждому свое)
    • НЛО прилетело и опубликовало эту надпись здесь
      • 0
        Я о том что есть выбор.
        1.Django+SQLAlchemy=кривонеподдерживаемоеинедокументированоетворение
        2.Pyramid(SQLAlchemy)=docs1+docs2
    • 0
      «Читать статью, потом комментировать». Повторять каждые полчаса в течении двух минут.
  • +4
    > SQLAlchemy может выразить любой SQL запрос (ну 80-90%)

    У меня вообще ощущение, что SQLAlchemy — это кому-то от нечего делать захотелось переписать SQL на Python. Типа, пишите вместо select xxx from yyy join zzz теперь SelectFactory(source_table=TableConstructor(xxx)).FromMapperShmapper(yyy, join_aggregation=JoinMapper(zzz))… Шутка юмора, конечно, но ощущение есть. Не пользуюсь. Где надо что-то сложное, там пора о schemaless думать.
    • НЛО прилетело и опубликовало эту надпись здесь
      • 0
        >>> mongo.users.save({"user": "Vassily", "groups": ["admins", "django gays"]})
        >>> mongo.users.save({"user": "Anatole", "groups": ["django gays", "kewl hakers"]})
        >>> mongo.users.find({"groups": "django_gays"})
        [, ]
        >>> mongo.users.find({"groups": "admins"})
        []
        >>> mongo.users.save({"user": "Darkwing Duck", "groups": {"cloak": "violet"}})
        >>> mongo.users.save({"user": "Batman", "groups": [{"cloak": "black"}, {"shmested": "woo"}]})
        >>> mongo.users.find({"groups.cloak": "black"})
        []

        Это дефолтный драйвер, есть более сахарные.
        Всегда ваш, КО.
        • 0
          О нет! Парсер схавал мой код!
          >>> mongo.users.save({"user": "Vassily", "groups": ["admins", "django gays"]})
          >>> mongo.users.save({"user": "Anatole", "groups": ["django gays", "kewl hakers"]})
          >>> mongo.users.find({"groups": "django_gays"})
          [Vassily, Anatole]
          >>> mongo.users.find({"groups": "admins"})
          [Vassily]
          >>> mongo.users.save({"user": "Darkwing Duck", "groups": {"cloak": "violet"}})
          >>> mongo.users.save({"user": "Batman", "groups": [{"cloak": "black"}, {"shmested": "woo"}]})
          >>> mongo.users.find({"groups.cloak": "black"})
          [Batman]
        • +1
          Каждый о своём :)

          Есть legacy проект с Django ORM, Михаил предлагает использовать SQLA для сложных запросов. Вы, видимо, предлагаете мигрировать на MongoDB?
          • 0
            Нет, не предлагаю мигрировать. Тяжелые данные вытащить в предназначенное для этого хранилище — это можно. Целиком переезжать никакого смысла нет.
            • +1
              Предназначенное для чего? Денормализация данных в рамках того же харнилища решает все те же проблемы, что и перенос «тяжелых» данных в MongoDB, но при этом не добвляет геморроя на сопровождение еще одного сервиса :)

              Грубо говоря, есть схема и есть запросы с большим количеством join'ов, которые Django ORM не осиливает. Варианты:

              1. Использовать SQLA для запросов (предложено Михаилом)
              2. Денормализовать схему, упростив запросы до возможностей Django ORM. Но возникают другие вопросы:
              (а) проблема синхронизации денормализованных данных
              (б) денормализованные данные тоже как-то нужно подготовить, здесь опять же могут появиться запросы, с которыми Django ORM не особо дружит :)
              3. Перекинуть агрегированные данные в MongoDB. Проблемы все те же, что и в пункте 2, плюс сопровождение MongoDB. В этом пункте не забываем, что возможности MongoDB в плане сложностей запросов не особо отличаются от Django ORM.

              • 0
                MongoDB это был пример. Есть разные базы для разных данных. Моя позиция — если в какой-то момент вы понимаете, что ваш Django-проект тормозит из-за SQL, надо избавляться от SQL, а не от Django.
                • +2
                  Эээээммм. Как бы ооооооочень редко Django-проект тормозит из-за SQL, чаще он тормозит из-за SQL, который генерит ORM и логично попробовать убрать ORM в начале из этой цепочки, а не SQL ;)
                • НЛО прилетело и опубликовало эту надпись здесь
                  • 0
                    … или выкинут Django целиком и перепишут все с нуля.
                    • НЛО прилетело и опубликовало эту надпись здесь
                      • 0
                        в школе и не такое бывает
                  • 0
                    Без проблем. Как-то раз таблица со всеми действиями пользователей, которые писались (и нередко читались в самых неожиданных комбинациях) для бехавиорального анализа, переросла 500 000 000 рядов и перестала вообще ворочаться в шарденом кластере. Перенесли ее на MongoDB в inline-документы, и она вроде бы там работает до сих пор. В другом проекте среди 20 000 000 товаров, у которых есть 50 000 разных атрибутов и 350 000 значений этих атрибутов понадобилось организовать фасетный поиск. Товары в CouchDB, из него River в Elastic Search, и все запросто пляшет и поет. Есть хороший опыт с переносом queue-like задач из ОРМ-а в Redis или в RabbitMQ. Представляю, как я бы алхмичил ради таких решений с SQL-ем :)
                • +2
                  Django-проект тормозит из-за Django ORM. Значит надо использовать что-то другое. Вроде всë верно и как раз про эту статью, не?
                • 0
                  «MongoDB is web scale».
                  Каждый видит, то что хочет, но зачем? Ну вот вы узнали о том, что не SQL единым, и теперь ищете тот самый гвоздь, это нормально, мы все так делаем. Но в статье то явно упоминается, что в Django просто нельзя достаточно хорошо контролировать конечный SQL, оттого и нужно иногда инструмент помощнее.
                  • 0
                    habrahabr.ru/post/204392/
                    для тех, кто не в курсе, вот перевод «MongoDB is web scale»
          • 0
            Мне кажется, что оптимальная стратегия — использовать mongo в качестве кэша, в т.ч. для тяжелых запросов, вроде генерации отчетов. Для непосредственно хранения данных он еще сыроват (больше всего расстраивает, что перебой с питанием сервера часто влечет за собой сложнопоправимый факаут БД).
            • +1
              Это у вас старенькие данные. Я ни в коем случае не монго-фан и привел его здесь просто как пример, но с 1.8-какой-то-там-версии там есть single node durability на основе журналирования, и по моим личным тестам оно работает хорошо.
              • 0
                Спасибо, видимо я отстал от жизни, надо будет пересмотреть возможность его использования.
      • НЛО прилетело и опубликовало эту надпись здесь
  • +1
    Решаем задачу написания кучи web сервисов и приплетать джангу к таким задачам вроде перебор. Решили использовать SQLA… а тут еще и оракл… да еще и стоит он RAC'ом… Джанге было бы пофиг на его позу, а для SQLA пришлось лезть внутрь чтоб сделать маленький патч… убили целый день и дружно ненавидим SQLA.
    Она сделана настолько… алхимически. Никаким KISS или вообще здравым смыслом внутри даже не пахнет.
    • 0
      А можете подробнее, если не сложно?
      • +1
        Когда оракл стоит RAC'ом, для подключения надо передать SERVICE_NAME, а не SID.
        Пришлось делать новый strategy, переопределяющий метод create.
        Казалось бы можно решить задачу в пару строк, а на практике чуть мозг не сломался.
        • +1
          Да, внутренности алхимии иногда расстраивают. :(
          • 0
            а что там у ней не так?
            • +1
              Не всегда всë просто и симпатично. Снаружи она очень клëвая, а внутри — очень сложная. Ну, это ожидаемо для фреймворков/библиотек такого уровня, но иногда прозреваю всë равно. :)
              • 0
                Ага (
                По этой же причине нормальных ОРМ, в отличии от фреймворков приложений, с трудом десяток наберется (я не только о питонячьей кухне)
            • +1
              фишка в том, что если ты захочешь залезть внутрь SQLAlchemy чтобы понять «а как тут вот это работает» то с 99% вероятностью ничего не получится. Во внутренностях она уж очень запутанная.
            • 0
              Например я хотел найти где хранятся параметры для плейсхолдеров внутри Query объекта, т.е. запрос

              q=session.query(Users).filter(User.id > 100)

              трансформируется в шаблон запроса с плейсхолдером

              SELECT * FROM users WHERE users.id = %{par_1}s

              и параметры для плейсхолдера

              {'par_id': 100}

              И я так и не смог найти (день искал, честное слово!) как из переменной q вытащить этот самый {'par_id': 100}
  • 0
    Если вам Django так не нравится, интересно узнать что же нравится?
    • +4
      Werkzeug, WTForms, Jinja2?
      • 0
        Что там сварга, кстати? :)
        • 0
          Более или менее забили в пользу фласка.
          • 0
            О, молодцы :) Если честно, фласк по уровню удобства дотягивает до джанги? Я не говорю про неебическую мощь алхимии, фантастическую скорость жинжи и прочих локальностей, а про качество связки этих компонент. У джинги, я считаю, её велосипедные компонтенты связаны между собой просто шикарно. Я пробовал год назад юзать фласк для маленькой проекта, он показался мне некомфортным. Например, не понял, как там интернационализацию сделать «как в джанге», чтобы шаблоны и код автоматом парсились и получался po-файл. Ну и конечно, админка. Это просто гениальная вещь в джанге (в плане юзабилити фреймворка, в плане маркетинга), да код говно там, но как оухенно нарисовать модели и получить готовый интерфейс для работы с данными. Во фласке есть что-то подобное? Я слышал был какой-то проект для алхимии, который позволял автоматически интерфейсы рисовать для веба.
            • +1
              Аппы для фласка растут взрывными темпами. Я даже и не могу сказать, что там уже есть, потому что мои сведения могут устареть внезапно.

              По ощущениям, на нескольких наших проектах flask работает отлично, разработка легкая, без косяков джанговских. Есть уже свои компоненты внутренние, что облегчает еще более.

              Суть конечно в том, что связка админки и БД только может быть. А во flask нет бд как бы.
              Вообще простенькую админку склепать это пара дней работы.
              • 0
                Так, админки нет, ясно. А что там с i18n — есть возможность автоматического построения po/mo файлов на основе размеченных данных из кода и шаблонов?
                • 0
                  C i18n там все волшебно, посомотрите flask-babel.

                  Да, все верно, админка возможна только под какой то интерфейс к БД, готовый.
                  • 0
                    Ага, с i18n вроде б норм. Я как бы не против фласка, не прочь его попробовать ещё когда-нибудь, но для в меру простого сайта на базе sqlite/postgres/mysql просто не вижу смысла — всё будет как в джанго за исключением того, что придётся админку велосипедить.
                    • 0
                      Django для в меру простого проекта подходит лучше чем что бы то ни было. Еще лучше django-cms.
                • 0
                  Кому ясно? :) packages.python.org/Flask-Admin/

                  Не, я знаю, сейчас начнется «нучотакактоубого уджангилучше» :) Спасибо, не надо.
                  А то я приведу неубиваемый аргумент «далучшеникак, чем какуджанги» :)
                  • 0
                    эта штука не работает с юникодом почему то. так что вряд ли она лучше
                    • 0
                      Я посмотрел, вроде как не лучше. Тоже CRUD на моделях.
                      • 0
                        > Тоже CRUD на моделях
                        У сварга-админки как то иначе?

                        Вообще довольно интересная тема, мне кажется.
                        • +1
                          У сварги вначале элемент меню. И каждый узел меню, вот эта штучка — svargahq.net/docs/shortcuts.bundle.html

                          Для CRUD был написан бандл, который предоставлял как раз все методы для модели. Поэтому в сварге CRUD лишь один из возможных элементов, и нет проблем с встраиванием какого-то альтернативного функционала.

                          Бандл я портировал в сваргу krivushinme.tumblr.com/post/10204763924/flask-and-api

                          Админку пока нет :) Может если сайт захочется перетащить со сварги на фласк, то займусь.
                          • 0
                            было бы здорово сделать какую-то гибкую админку для фласка, это бы очень-очень помогло!

                            сами сейчас делаем большой проект на фласке )

                            есть некоторые мелкие недочеты вроде отсутствия поддержки gettext в Flask-WTF (чтобы русифицировать ошибки встроенных валидаторов), но если эти мелочи легко решить… то вот с админкой пока даже не знаю как лучше поступить…

                            сам к сожалению сваргу не использовал, не довелось как-то
                            • 0
                              > есть некоторые мелкие недочеты вроде отсутствия поддержки gettext в Flask-WTF (чтобы русифицировать ошибки встроенных валидаторов)

                              Нужно передавать объект с методами gettext(), ngettext() в параметр _translations при объявлении свойства формы при __init__ объекта поля.
                              И все будет ок ,)

                              Либо можно немного подправить валидаторы, например так:
                              REQUIRED = validators.required(_('This field is required.'))
                              

                              Так еще проще.

                              > с админкой пока даже не знаю как лучше поступить…
                              Напишите.
                              • 0
                                угу, я им отписался, они молчат…
                                видимо готовый патч надо сразу слать чтобы включили.
                                не хочется свой форк делать )

                                посмотрю ваши bundle, попробую что-нибудь придумать, спасибо :)
                          • 0
                            Конечно бандл выгодно отличается от блюпринта. Удобно! )

                            Все таки, как я и думал, всплывает очевидный вопрос:
                            «Все хотят авто генерируемую админку, а Вы предлагаете её усложнить на столько, что она будет конфигурироваться чуть быстрее чем самаписная под проект. Дак есть ли в этом смысл? Стоит ли ломать копья?»

                            Ответ, имхо, тоже очевиден:
                            «Необходимо найти некий компромисс, при котором возможен максимально быстрый старт, как, например у django. Но чтоб это было не в ущерб гибкости настройки.
                            И это, конечно, высшая творческая задача.»

                            Есть ли бутстрапы без мана на 10 экранов к сварга-админке? =))
              • 0
                Аппы — это значит надо что-то гуглить и ставить допольнительно? «Изкоробки» нет?
                • 0
                  Да, у фласка нет контриба. Много пакетов написано самим Армином, но ставить отдельно. Впрочем с pip и virtualenv это давно уже никого не волнует.
        • 0
          Да, после того как Армин собственно сам уже написал полноценный фреймворк, переориентировались на перетаскивание из сварги полезных кусков.
          • 0
            Полезные куски? Есть что то посомтреть из этого?
            • 0
              Пока нет. Но в общем хорошие вещи, которые родились в сварге:
              1. amalgam, орм с бекендами. Есть поддержка SQLA, и вроде была GAE.
              2. Bundle — мелкая полезная штука, наподобие блупринтов, но класс.
              3. связка с opster. Александр хотел прикрутить опстер под фласк, будет хорошо, как мне кажется.

              4. Можно еще на админку посмотреть, она правда не оконченная была.

              Может еще что потом вспомнится.
              • 0
                круто!

                На сколько я вкурсе, Rodrigo Moraes хотел дописать amalgam для Datastore(GAE), но у него как то стухло все с tipfy…
                Идея, которая недает покая — дописать amalgam еще и под mongoDB(к примеру) и сделать админку через нее.

                У Вас админка стоит формы по моделям SQLA или amalgam? Принципиальный вопрос ))
                • 0
                  Админка по-большей части все таки на SQLA заточена. С другой стороны мне сейчас уже не кажется, что можно один и тот же ОРМ, amalgam, прилепить к таким разным БД, и оно действительно будет хорошо работать.
                  Если GAE и Mongo еще как-то сводятся в одному знаменателю, откидывая специфичные фишки, то привести туда же Redis уже не видится простым, да и вообще вменяемым, решением.
                  • 0
                    > привести туда же Redis уже не видится простым, да и вообще вменяемым, решением.
                    С этим сложно спорить.

                    Михаил, спасибо за статью. Отличная получилась дискуссия!!! Правда карма и у меня тоже сильно упала =) Но это не интересно. А интересно то, что у людей с трезвым взгядом на предмет обсуждения всегда есть выбор. А если есть выбор, появляется возможность быть более гибким в различных ситуациях. Возможность выбора отличает успешных людей, факт.
                    • 0
                      Черт, чужую карму жалко. Баламутил то по-черному я :)
                      А вообще мы больше общаемся не через хабр конечно. Twitter, g+ и тп.
    • +3
      Статья в общем то не об этом, но я согласен с ingspree. Flask, Jinja2, SQLAlchemy. И еще много разных библиотек.
    • 0
      Tornado еще очень милый.
  • 0
    Нет, я конечно понимаю что джанговский ORM ограничен, но откруда столько агрессии?

    Я тоже упирался в то что запрос был не простым, правда решилось все использование джанговских костылей, в частности работа напрямую с through-моделью.
    • +1
      Это клëво, но идея в том, что такое выразить джангой как-то тяжело:

      items = (GuestListEntry.query(GuestListEntryDispatch, EticketDownloadHistory)
               .outerjoin(GuestListEntryDispatch)
               .join((Order, (Order.client_id == GuestListEntry.id) &
                      (Order.is_guest == True)))
               .outerjoin(EticketDownloadHistory)
               .filter(GuestListEntry.batch_id == batch.id)
               .all())
      
      • 0
        Я к сожалению не очень знаю SQLA чтобы преобразовать это в обычный SQL и подумать, как это реализовать в Джанге.

        Да я и не спорю, что SQLA мощнее, и при этом немного «низкоуровнее».

        Просто не пойму, зачем брызжать слюной и кричать о том что ненавидишь Django и что джанго-разработчики какие-то упоротые.

        Вам, кстати, спасибо за пару примеров сложных запросов.
        • –2
          Это ваше личное восприятие. Ни одна брызга не долетела до монитора в процессе написания топика, гарантирую.

          А вот рассуждать об уровнях, когда вы сами только что сказали, что SQLA в упор не знаете, как то наивно, нет?
          • 0
            Я ничего не имею против того, что написано в статье, об уровнях не рассуждаю и аргументы в споре DjangoORM vs SQL Alchemy не привожу.
            Мне сам стиль изложения не понравился.
            • 0
              А, это возможно. В этот раз я выбрал именно провокативный стиль. Буря в комментах свидетельствует, что какой-то эффект это имело.
      • 0
        можете это же самое в raw sql предоставить? спасибо
        • 0
          Тут и перекладывать то нечего — как видим так и пишем)
          (GuestListEntry.query(GuestListEntryDispatch, EticketDownloadHistory)
                   .outerjoin(GuestListEntryDispatch)
                   .join((Order, (Order.client_id == GuestListEntry.id) &
                          (Order.is_guest == True)))
                   .outerjoin(EticketDownloadHistory)
                   .filter(GuestListEntry.batch_id == batch.id)
                   .all())
          ==
          SELECT GuestListEntryDispatch.*, EticketDownloadHistory
          FROM GuestListEntryDispatch, EticketDownloadHistory
          OUTER JOIN GuestListEntryDispatch
          JOIN Order ON (order.client_id == GuestListEntry.id AND Order.is_guest == true)
          OUTER JOIN EticketDownloadHistory
          WHERE GuestListEntry.batch_id == batch.id
          • 0
            спасибо)
            Из этих двух вариантов я думаю многим будет проще заюзать в джанго raw-селект, чем писать sqla.
            • 0
              Да, это так. Если это один такой селект у вас. У меня в проекте попалась пачка весьма схожих запросов, но вот мелкие детали сделали невозможным привнести DRY на уровне строк.
              • 0
                Конечно не знаю конкретной вашей задачи, но как вариант обернуть текст raw запроса в функцию с параметрами?..
                и если необходимо — добавить ее как метод необходимого класса-модели…
                • 0
                  Не выйдет, будет очень уж монструозно — например у меня там могут быть джойны по разным таблицам, разным условиям, а какие-то части у них один в один. Делать магию со строками — писать недогенератор запросов на коленке.

                  Плюс к тому проект о финансах, и там отчетов напридумали кучу. И все эти отчеты сильно выиграют от интеграции SQLA в проект.
          • 0
            Дайте нормальный SQL, этот явно не рабочий. GuestListEntry, например, возникает только в WHERE
            • 0
              Так оно на самом деле:

              SELECT * // тут все поля будут перечислены явно для GuestListEntryDispatch и EticketDownloadHistory
              FROM GuestListEntry
              OUTER JOIN GuestListEntryDispatch // ON условие пропущено, 
              // на самом деле оно в определении relationship
              // поэтому я его не смогу написать, но оно будет
              JOIN Order ON (order.client_id == GuestListEntry.id AND Order.is_guest == true)
              OUTER JOIN EticketDownloadHistory // и тут ON не написать без определения
              WHERE GuestListEntry.batch_id == %% // а здесь плейсхолдер на самом деле
              
            • 0
              Да, не доглядел момент насчет GuestListEntry — у нас просто запросы по другому немного принято записывать — через Session. Наподобие: Session.query(GuestListEntryDispatch, EticketDownloadHistory).join(GuestListEntry),...
              Боюсь без автора или DDL не смогу написать.

              Кстати, чтобы посмотреть какой SQL оно сгенерирует, достаточно сделать str() объекту запроса.
      • 0
        Выполните этот запрос и дайте на SQL, пока ничего сложного не вижу.
        • 0
          А в нем и нет ничего сложного. А сложный я вам дать не смогу, придется еще полпроекта дать. Все models.py, и собственно reports_queries.py, который в объеме 500 строк. А так как проект собственно закрытый, то это уже несколько выходит за рамки того, что можно показывать наружу.

          Но неужели вам действительно нужно доказывать, что некоторые вещи на джангорме не сделать?
    • +1
      Это не агрессия, это экспрессия, тёма-стиль изложения. Цель ввести читателя в состояние сильного возмущения, чтобы он бросил читать статью после первых двух строк, и потом измываться над ним за это в комментах. Жаль только карма страдает так сильно, что на следующую статью уже может и не хватить :D
      • 0
        А, вот оно что.
        Жаль на мне не сработало, дочитал до конца.
      • 0
        Подкинул на всякий пожарный.

        А с экспрессией переборщили. Хотя я видимо я еще не познал той глубины гемора в работе с django, чтобы поддержать ваш настрой.
  • +3
    По сабжу — мне кажется что библиотечка охрененная. Можно использовать все возможности Django а сложные запросы писать в алхимии.
    Если напишете в README побольше примеров будет совсем здорово. Вообще примеры бы не помешали, пока не до конца понятно как с этим работать. Возможно буду пользоваться.

    Ну и пара вопросов:
    * Я так понял алхимиевские модели на лету генерируются… А есть ли возможность их как-то кастомизировать?
    * Оно использует то-же соединение с БД что и джанга или создает отдельное?
    * С транзакциями дружит? Т.е. можно ли в пределах транзакции часть запросов сделать в SA а часть в Django и нормально ли на это отреагирует маппер?
    * Использование вашей библиотеки сколько оверхеда добавляет? Хотябы ориентировочно… Я так понимаю все генерируется в момент импорта, а не при каждом обращении?
    * Что делать с кастомными полями?
    • 0
      Промахнулся с ответом, он ниже.
  • 0
    1. Модели генерируются при загрузке приложения. Кастомизации не предусматривалось, но в принципе можно и подумать. Только вот тут уже действительно вначале юзе кейс нужен, чтобы сделать то что надо.
    2. Да, идет реюз соединения
    3. Есть фишки с закрытием транзакций в Django. Так как я использую sqla для выборок, а не для вставок — проблем не возникает
    4. Да, модели генерируются один раз. Конечно SQLA кушает свою память, но в момент самого запроса ничего не генерируется заново
    5. Хм, кастомные поля это уже сложнее. С другой стороны любое кастомное поле имеет под собой что-то вполне материальное — VARCHAR, INT, TEXT. На данный момент работа с ними будет именно в таком вот, сыром виде.
  • 0
    Так хорошо начал, а потом SQLAlchemy хорошим решением назвал… как водой окатило.
    • 0
      А вы что используете? SQLA в решении моей проблемы вполне помог, и он явно лучше raw sql.
    • 0
      Когда можно ожидать «б»?
      • 0
        Стараемся использовать нереляционные базы данных. Когда вижу код с использованием SQLAlchemy сразу же начинает что-то дергаться. В практике оказывается всегда хуже чем выглядит.
  • +12
    Библиотечка полезная может быть, если нужно от БД отвязаться для каких-то сложных запросов, с месяц назад заметил на гитхабе ее.

    А вот срач достал очень, понты все эти, кто какой крутой питонщик и кто какой крутой джангист, провокации, вторые смыслы у вроде бы технических статей, манипуляции, комменты в духе ты дурак, т.к. пишешь на пэхэпэ (варианты: на джанге, на питоне, не на ерланге, не знаешь haskell и т.д.) а я д'Артаньян и тд., не стоят технологии того. Повод поворчать и поругать код всегда найти можно: вот прикручивал я WebTest из Pylons к django — штука хорошая, что получилось — нравится. И что, нужно было что-ли писать статью «джанго — дерьмо, и даже тест-клиент у него дерьмовый, а вот в пилонсе все круто» или «ну и дерьмо же ваш пилонс, парсинг html на регэкспах, причем неправильный, юникод не поддерживается совсем, весь код в одном файле на 50k и полторы тыщи строк, столько всего исправить пришлось, прежде чем хоть как-то пользоваться можно стало, и вообще, у WebTest с пилонсом интеграция сейчас хуже, чем с джангой, клево да». Ну кому все это нужно, желтизна эта и срач, ну весело, конечно, было бы, типа вот кашу заварил а эти хомячки комментируют, и даже на мнение людей о технологиях повлиять можно, но блин, не несет срач пользы человечеству. Люди не идиоты, если технология хорошая и понятно, почему, то ей будут пользоваться. А вот когда пытаются описать преимущества технологии через «опускание» конкурентов, это всегда настораживает. Мне это в джанге очень нравится — в рассылке вот недавно было предложение на главной написать, что, мол, джанго, крутая штука и у нее куча преимуществ по сравнению с другими технологиями, реакция человека ответственного за это (Jacob Kaplan-Moss) — «только через мой труп» («only over my dead body»): если и говорить о достоинствах, то говорить предметно, без срача и неуважения к подходам других программистов. Угу, набегайте теперь и пишите, что у джанги нет достоинств по сравнению с другими технологиями, подтверждая все вышенаписанное.
    • 0
      Если честно, то первые строчки просто мое отношение к джанго. Манипулировать даже и не пытался. За каждый пункт я могу ответить предметно, почему именно в джанго плохо сделаны орм, шаблоны, формы и тп.
      А ругать полезно, особенно когда ругают конкретные моменты. Но вот в случае джанго орма даже ругать нечего предметно. Нормальному человеку и так понятно, что он ничего не может за рамками простейших селектов.
      • 0
        > ничего не может за рамками простейших селектов

        так бы и сказал что не осилил…
        • –1
          Опять же, с незнакомыми людьми мы общаемся на вы. Это вы не осилили алхимию.
      • +2
        >За каждый пункт я могу ответить предметно, почему именно в джанго плохо сделаны ОРМ, шаблоны, формы и тп.
        Ну так пиши предметно, зачем постить высер вся суть которого сводится к «не хватает джангоорм, попробуйте алимию». На мой взгляд, ты просто не проникся духом питона, отсюда и лучи ненависти.

        • –3
          Во-первых на вы. Во-вторых уже писали, но хомячки не заметили.
          • +1
            Когда в онлайне переходят на Вы, в оффлайне уже бьют в морду
            • –2
              О, как экспрессивно! И такая подпись на экране «когда слов уже не осталось, скажи собеседнику „вЫЫЫЫ!!! УУУУУ, Абырвалг!“.
            • 0
              ух, отлично сказано. нужно запомнить )

              правильно, в интернете все равны. а равным людям обязательное обращение на вы (дабы потешить своё тщеславие) не требуется.
              • 0
                Люди нигде не равны, но суть не в том.

                Обращение на `вы` это форма вежливости между равновежливыми людьми. Равноневоспитанные люди тыкают друг другу, когда к этому нет никаких оснований, в виде давнего знакомства, когда `вы` звучит уже как-то стремно.

                Поэтому даже к вам, хотя у меня нет никаких оснований считать вас некой особой личностью, я обращаюсь на вы — это вежливость.
        • 0
          Хотя бы так solovyov.net/blog/2008/10/06/dark-side-django/
          Еще был доклад на конференции pyconua.
          Не вижу смысла повторяться ради вас.
          • 0
            2008 года пост у piranhи ) джанга уже не та.

            Но почему я ей до сих пор пользуюсь? Ответ стар как мир — ничего лучше я не видел. RoR — это вообще сам Тартар, Pylons — это его младший брат, и оба переполнены магией выше крыши не только внутри, но и в приложениях. Этим джанга хороша — несмотря на то, что там внутри происходит, все приложения очень часто абсолютно прозрачны и просты для понимания. Главное — не пытаться сделать то, чего Джанга не позволяет. Она этого не любит.


            а если джанго орм не подходит (хотя даже сложный sql запрос в принципе можно пустить напрямую), наверное проще отказаться отджанги совсем в пользу чего-нибудь вроде flask или pyramids.

            я не «эксперт» =) джанга нравится, для моих задач подходит полностью + стараюсь избегать сложных запросов к бд (все эти джоины — бррр).
            • 0
              Тогда еще не родился flask. И Александр же в соавторстве написал Svarga, именно по той причине, что джанга уже не та.

              Про джойны — а они есть. Вы их не видите, потому что не смотрите на сам запрос, который джанго выдает, а там этих джойнов гора.

              Про отказ — а я и отказался, и делать новые проекты на джанге, где я буду в качестве разработчика, отказываюсь.

              Про сложные запросы хорошо описал в этом топике Юрий Юревич — если денормализацию делать, то начнется история с поддержкой этой денормализации. Это не говорит о том, что денормализация плохо, просто в некоторых случаях не стоит свеч, когда можно просто запрос сделать посложнее. Отчеты, в которых обычно и нужны сложные выборки, вызываются редко, и оптимизироваться под них сильно не стоит.
              • 0
                ага. прочитал тут дискуссию касательно flask, очень интересно, нужно будет посмотреть более пристально на него )

                не так давно думал использовать его: читал документацию, делал простейшее приложение — глубоко не вникал. вообщем приятно удивлён тем, что проект развивается и оказывается там уже есть масса готовых решений, нужно будет взглянуть на всё это.

                мы, кстати немного знакомы какое-то время я частенько задавал вопросы на python.ua )
                • 0
                  Flask уже собственно используется активно.
                  А на pythonua видимо был другой ник :)
  • +2
    Говнотопик получился. Автор признался, что специально написал пост в правокационном стиле, а затем требует соблюдения этикета. И рыбку съесть и на… сесть? Так не бывает :) Люди чувствуют такие моменты.
    • –3
      Нормальный топик, комменты дурацкие. Из всей массы хороших 3 штуки. А провокативный он только для django guys был. Только они и реагируют на первые строчки, остальные это и так все уже знают.
      • +1
        Я в понятие топик включаю комменты. Значит, ты частично согласен с тем, что топик говно в моей системе определений. Комменты — это дети. А ты их родитель, так сказать. То что комментарии дурацкие, в первую очередь твоя заслуга :) Топик пропитан твоими эмоциями, вместо того, чтобы писать между строк, что джанго говно, лучше бы (для более продуктивного обсуждения) указал больше реальных примеров совмещения джанго орм и алхимии, случаи и байки из жизни, анекдоты, в общем, что-либо позитивное.
        • –2
          А вы упорный хам. Я считаю, что все пошло именно в том русле, в каком оно должно было пойти.
          Я написал топик, потом вылезли «эксперты», со стандартными вопросами и предложениями, которые меня уже давно и конкретно утомили.

          Я просто неожиданно понял, что постить на хабр и выслушивать экспертные мнения мне как-то уже надоело. Я лучше на стэндалончик переберусь, и буду банить активно. Вот это жизнь, вот это счастье, будут мои топики мягкими и шелковистыми, без экспертиз, а с нормальными обсуждениями. Тут что-то через край демократии.
          • +1
            Просто пишу правокационные комментарии к правокационному топику. Ни больше не меньше. Вообще я своими мыслями поделился, если за резким тоном вы их не заметили (и стали обсуждать мои личные качества), то почему вы удивляетесь дурацким комментариям к вашей статье? Я понимаю, что вы их и ожидали увидеть. Только зачем вам это? Это равносильно тому, что зайти в стадо овец и сказать: ну тупыыыые и самодовольно усмехнуться :)

            > Тут что-то через край демократии.
            Согласен. Считаю, что качество обсуждений на хабре существенно страдает от того, что вы, я и другие люди могут тупо бычить и оскорблять других людей прямо или завуалированно.
            • 0
              Нет, качество хабра страдает от того, что каждый может высказать свое «экспертное» мнение, и тупо забанить его нет никакой возможности.
            • +1
              Кстати топик вполне себе нормальный. Если кого-то сильно провоцирует факт, что у джанго масса недостатков, которые просто очень долго будут исправляться эволюционным путем, а часть вообще не будет из-за позиции авторов, то это недостаток опыта и знаний.
              • 0
                Что вы дурачком прикидываетесь. Людей задевает не тот факт, что вы указали на недостатки джанги, а то как вы это сделали. Вы уже писали выше, что топик нормальный. От того, что вы это повторите во второй и третий раз ничего не изменится :) Джанго прекрасный инструмент, многим нравится, зачем там что-то исправлять? Я вот клепаю мелкие сайтики на джанго и вполне счастлив. Джанго это грубо говоря джумла, друпал, своеобразная CMS. Она выросла из сайта для новостей, отсюда и её специфика. У джанги есть прекрасная админка, которую используют по прямому назначению — добавлению, редактированию контента.

                Подумайте, если сильно не нравится, значит инструмент не для вас, не для ваших задач. То что люди не думали изначально, что вырастут из джанги, или то что люди знали ограничения, но всё равно её выбрали или то что люди работают с тем, что им досталось, вовсе не означает, что джанго говно. Просто это означает, что конкретно тот, кто сейчас работает с джангой в этом проекте — он в говне. Пособолезнуем ему.
                • –1
                  Админка у джанги такая же убогая, как и все остальное.

                  А соболезновать не надо, надо радоваться, что люди могут решать проблемы. Я вот решил насущную. То что там шаблоны неудобные и прочее, это неудобство, а вот с запросами как раз была беда.
                  • 0
                    Она лучше, чем её полное отсутствие. Не было бы у джанги админки я бы до сих пор писал CLI-скрипты на php :) Для веба я питоном не проникся (не осилил развёртывание и администрирование), но вот для CLI он оптимален, имхо. Спасибо всем, кто его создавал и помог мне его узнать (включая создателей Jango).
                    • 0
                      Да, она подкупает. Только как и обычно — админка неплохой инструмент, но только для суппорта, который сам в состоянии сайт разработать.
                      Даже просто построить что-то полезное поверх практически невозможно — уж так ее изначально спроектировали. То есть пошли плясать от моделей, а не от собственно админки, в которой модели это малая часть.
                      Недописанная админка в сварге по идеям на голову лучше. В одном проекте даже вполне ее запилил как основной инструмент администрирования.
  • +2
    Использовать везде один ORM, а в качестве fallback-a другой — это ПП. Тем более, что иногда ещё и до SQL будет доходить. Сейчас не поленился грепнул один свой проект на джанге:

    Запросов через ORM — 500 (не считаем Model.save(), .delete(), related ацессоры, вариации одного запроса с разными фильтрами, порядком, count() на тот же queryset).
    Запросов на SQL — 15.
    Есть ещё SQL запросы к внешним базам, DDL, интроспекция и платформная специфика, их выкидываем потому как это вне компетенции ORM.

    В итоге ORM покрывает 97% запросов при весьма либеральном подходе, при переходе на другую базу проще подправить эти 15 запросов (если придётся), чем всё приложении заранее писать на другом ORM. Пусть SQLAlchemy покроет 99%, вместо 15 SQL запросов у меня будет 5, зато все те 500 будут на более низкоуровневом SQLAlchemy, мой код сразу станет гораздо менее простым.
    Это всё к автору, который считает, что мы со своим Django ORM неизбежно будем тыкаться в его ограничения.

    Возможно у кого-то проект другой и запросы другие, тогда, может быть, SQLAlchemy там будет лучше.

    Напоследок ещё один гвоздь в SQLAlchemy — кеширование. Сложные запросы кешировать тяжело, они зависят от большого количества вещей и поэтому их сложнее инвалидировать (или чаще). Кроме того, запрос к кешу, как правило, дешев, поэтому запрос разбирается на кусочки, каждый из которых кешируется и инвалидируется отдельно. Сложные запросы уходят — для простых запросов лучше ORM попроще, который сделает более читаемым и более DRY оставшийся код.
    • –1
      Не надо за автора думать.

      Я считаю, что в моем проекте нужно взять SQLA и не мучаться. В вашем видимо не надо. Вот так все просто на две строчки.
    • 0
      Думаю это очень от специфики проекта зависит. Если интересно — может приведете запросы, которые у вас на SQL? А мы попробуем их в SQLAlchemy написать.
      • 0
        Просмотрел ещё раз всё довольно специфично:
        select ... for update;
      • 0
        select ... from a join b (a.id = any(b.descendants)) -- b.descendants - int[]
        insert into ... select ... from ...
        update ... from (values ...) where ...

        в таком духе.

        Плюс несколько случаев, которые и на джанго можно сделать, просто ради простоты или эффективности написали SQL.
        • 0
          Это можно записать на SQLA, а нужно ли, вам лучше видно :)
    • +2
      > Пусть SQLAlchemy покроет 99%, вместо 15 SQL запросов у меня будет 5, зато все те 500 будут на более низкоуровневом SQLAlchemy, мой код сразу станет гораздо менее простым.

      Посылка не верна.

      1. Автор говорит, что он хочет заменить вот эти 15, а не все 500.
      2. У меня нет подтверждающих ссылок, но есть ощущение, что SQLA умеет весь ANSI SQL. Так что с очень большой долей вероятности получится заменить все 15 запросов.
      3. Автор предполагает, что вы проведете анализ своих SQL запросов до того, как внедрять SQLA в Django проект :-)

      То, что автор изложил свою информацию так, что ее почти не видно из-за набросов на Django, оставляю на совести автора :-)
  • +2
    Вот уж действительно у змееводов яд появился… Ребята, что с вами?
    Человек написал либу и объяснил зачем она может понадобиться. Если вам она не нужна (или вы не поняли, зачем она нужна), так не пользуйте! Но зачем грязь-то друг на друга лить?
    Давайте жить дружно!
  • –1
    pre code без скроллинга? бееее, чуть не вырвало
    • 0
      source тег хабра
      • 0
        отмазался типа)
  • 0
    Михаил, Вы написали отличную и полезную библиотеку.
    Не стоило так растрачивать себя на малолетние споры о необходимости использования более гибких SQL-конструкторов в Джанго. Это и так очевидно для любого человека с опытом разработки на Джанго.
    А для тех кому это не очевидно (по причине опыта), — Ваша библиотека просто не нужна, и не стоит никого убеждать ее использовать.

    На Джанго Вы, конечно, зря так наехали. Не без «узких мест» конечно, но зато представляет из себя прекрасную экосистему, объединяющую огромное количество разработчиков. На все случаи жизни найдутся готовые решения. Тут трудно найти более более удачный пример.

    Справедливости ради, стоит отметить, что в Джанго можно использовать только лишь sqlalchemy.sql, а не весь sqlalchemy. А результат его работы подставлять в Manager.raw(). Возникнут небольшие траблы в паджинацией, но это легко решаемо.

    Ваш путь конечно лучше, и предпочтительней, но не без недостатков.

    Во первых, Вы сильно привязываетесь к не задокументированному API, стабильность которого никто не гарантирует (а насколько быстро Вы будете реагировать на его изменения, — не известно). Правда, библиотека не большая, и ее можно сопровождать самому, — но все же вопрос остается.

    Во вторых, — если используется в проекте GeoDjango, — нужно дорабатывать Вашу библиотеку, чтобы она распознавала новые типы полей и позволяла работать с www.geoalchemy.org/

    В третьих, нужно решать вопрос расшаривания соединения, транзакций и пр., но вы вроде бы эти вопросы решали.
    • 0
      Извиняюсь, двусмысленно выразился.

      Не «что в Джанго можно использовать только лишь sqlalchemy.sql», а «что в Джанго можно ограничится использованием только sqlalchemy.sql»
    • 0
      Manager.raw не поможет с подгрузкой o2m и m2m связей через подзапрос, насколько я вижу — нужен класс на который отображается результат sqla.

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.