• Какое минимальное количество файлов должно быть в проекте и с каким содержанием, чтобы задеплоить скрипт на Heroku?

    sergey-gornostaev
    @sergey-gornostaev Куратор тега Python
    Седой и строгий
    Достаточно одного python-скрипта и одного Procfile, в котором записана команда для запуска скрипта. В скрипте должен, как минимум, открываться сокет, обслуживающий подключения. А результат вы увидите в том случае, если он будет в сокет записан.

    С использованием Flask, например:

    app.py
    import os
    import sys
    from flask import Flask
    
    app = Flask(__name__)
    
    @app.route("/")
    def hello():
        return sys.version[::-1]
    
    if __name__ == "__main__":
        port = int(os.environ.get('PORT', 5000))
        app.run(host='0.0.0.0', port=port)

    Procfile
    web: python app.py
    Ответ написан
    2 комментария
  • Как задать несколько изображений на странице товара в БД?

    riot26
    @riot26
    <:З )~~
    Отдельную таблицу. `product_images` (`product_id`, `file_path`)
    Ответ написан
    Комментировать
  • Как обратиться к атрибуту объекта динамически?

    sergey-gornostaev
    @sergey-gornostaev Куратор тега Python
    Седой и строгий
    attr_name = 'created'
    sort_by = getattr(Model, attr_name).desc()

    Но вообще для подобных задач лучше использовать движки полнотекстового поиска, типа Elasticsearch.
    Ответ написан
    Комментировать
  • Оператор // в Python?

    chupasaurus
    @chupasaurus
    Сею рефлекторное, злое, временное
    В Python целочисленное деление округляет вниз, чтобы остаток всегда был неотрицательным, сделано это для удобства. Комментарий Гвидо.
    Ответ написан
    Комментировать
  • Как написать функцию итератор?

    Melkij
    @Melkij
    PostgreSQL DBA
    Это называется не итератором.

    insert into terms (term, freq) values (?, 1) on conflict (term) do update freq = excluded.freq + 1 returning freq;

    В функцию завернуть по желанию. 9.5+
    Ответ написан
    Комментировать
  • Почему не выводит строки при корректном запросе postgre?

    Melkij
    @Melkij
    PostgreSQL DBA
    А с кавычками выводит "ничего" т.е. ноль полей.

    С какими именно?

    user='40'
    'user'='40'
    "user"='40'

    Это три абсолютно различных условия, выполняющих совершенно разные вещи.

    user - зарезервированное слово по требованию стандарта. По стандарту не уверен что обозначает в контексте where, надо искать (может как часть create user и подобных только зарезервирован), а в postgresql обозначает имя текущего пользователя. Имеет тип name, что и провоцирует ошибку.
    Т.е. первое условие в принципе не имеет никакого отношения к каким-либо пользовательским таблицам.

    'user' - просто текстовая константа. Никто не мешает в условии сравнивать одну константу с другой, where 1=1 в некоторых query builder отсюда же.

    "user" - обращение к объекту, игнорируя зарезервированные слова. То есть если у вас в таблице proxy есть поле user - то запрос должен быть записан как
    select * from proxy where "user"='40'

    Но общая практика - лучше не надо использовать зарезервированные слова в качестве идентификаторов.
    Ответ написан
    1 комментарий
  • Как начать работать разработчиком SQL без тех образования?

    У меня ни разу не спрашивали о высшем образовании (которого у меня нет). Работодателя интересует только знания и навыки
    Ответ написан
    1 комментарий
  • Userid или user_id?

    sergey-gornostaev
    @sergey-gornostaev
    Седой и строгий
    В сферическом SQL в вакууме принято использовать snake case. Но на практике следует придерживаться стиля принятого для проекта.

    SQL Style Guide
    Ответ написан
    Комментировать
  • Как отфильтровать значения связанных полей в django admin?

    sergey-gornostaev
    @sergey-gornostaev Куратор тега Django
    Седой и строгий
    Путь web-разработчика должен начинаться с понимания, что сайт - это на самом деле не одно приложение, а два, написанные на разных языках, работающие на разных компьютерах, в разном окружении и в разное время.

    В случае Django работу сайта можно разбить на следующие этапы:
    1. Пользователь запустил браузер и ввёл адрес сайта
    2. Браузер установить tcp-соединение с сервером
    3. Браузер отправил в соединение http-запрос
    4. Сервер в ответ на запрос запустил соответствующий python-скрипт
    5. Python-cкрипт в процессе работы сформировал некоторое количество текста и отправил в tcp-соединение
    6. Python-скрипт завершил работу
    7. Браузер принял весь текст от сервера и закрыл соединение
    8. Браузер проанализировал полученных текст и нарисовал пользователю html-форму


    Все дальнейшие действия пользователя будут обрабатываться только в браузере, самим браузером и\или javascript'ом. И javascript, и браузер будут работать с теми данными, которые получили от сервера. Если понадобятся другие данные, придётся повторить операции из списка выше, или с помощью отправки формы или с помощью ajax-запроса.

    Отсюда ответ на ваш вопрос, если хотите изменения данных в выпадающих списка формы, вам придётся написать javascript-обработчик изменения полей формы, делающий ajax-запросы к серверу и изменяющий значения полей формы в соответствии с полученными от сервера данными, а так же дополнительные представления на сервере для обработки этих ajax-запросов. Для этих целей можно попробовать использовать готовое решение - django-select2.
    Ответ написан
    1 комментарий
  • Как добавить несколько изображений в django?

    sergey-gornostaev
    @sergey-gornostaev Куратор тега Django
    Седой и строгий
    Сначала делаете миграцию с новым полем, а потом добавляете его в форму.
    Ответ написан
    Комментировать
  • Как в django вывести в шаблон count всех объектов подподкатегории?

    sergey-gornostaev
    @sergey-gornostaev Куратор тега Django
    Седой и строгий
    Прежде всего, если используете иерархические структуры данных, то используйте их с django-mptt. Во-первых, это позволит работать с любым уровнем вложенности, в том числе неопределённым на этапе разработки и переменным в разных ветках. Во-вторых, это облегчит вам работу, предоставив простые и эффективные методы манипуляции ветками. Наконец, это позволит получать данные из БД наиболее быстрым и эффективным способом, с минимальной затратой ресурсов.

    Конкретно по вашей задаче решением в лоб было бы определить в модели свойство, возвращающее количество объявлений в дочерних категориях:
    class Category(models.Model):
        parent = TreeForeignKey('self', verbose_name=u'Родитель', null=True, blank=True, related_name='children')
        title = models.CharField(u'Название', max_length=100)
    
        @property
        def items_count(self):
            # получаем список идентификторов всех низлежащих категорий, включая интересующую нас
            ids = self.get_descendants(include_self=True).values_list('id')
            # возвращаем количество товаров, имеющих родителем категорию с идентификатором входящим
            # в список полученный строкой выше
            return Product.objects.filter(parent_id__in=ids).count()

    и потом вывести их в шаблоне как-то так
    <ul class="root">
        {% recursetree nodes %}
            <li>
                {{ node.title }}<span>{{ note.items_count }}</span>
                {% if not node.is_leaf_node %}
                    <ul class="children">
                        {{ children }}
                    </ul>
                {% endif %}
            </li>
        {% endrecursetree %}
    </ul>

    Но беда в том, что это квадратичный алгоритм, чем больше будет категорий отображаться на странице, тем больше запросов будет к базе при открытии этой страницы. Я так и не нашёл в Django лучшего решения для этого, чем делать сырой SQL запрос к базе:
    SELECT name, cp.p_count FROM catalog_category AS cc
    INNER JOIN LATERAL (
      SELECT cc.id AS id, SUM(products) AS p_count FROM (
        SELECT cc.id AS parent_id, category_id, COUNT(id) AS products
        FROM catalog_product
        WHERE category_id IN (
          SELECT id FROM catalog_category
          WHERE lft <= cc.rght AND lft >= cc.lft AND tree_id = cc.tree_id)
          GROUP BY category_id
        ) AS sub_cс
      GROUP BY parent_id
    ) AS cp
    USING(id) ORDER BY name;
    Ответ написан
    5 комментариев
  • Суммирование переменных, как это сделать?

    sergey-gornostaev
    @sergey-gornostaev Куратор тега Jinja
    Седой и строгий
    {{ get_items() | sum(attribute='price') }}
    Ответ написан
    1 комментарий
  • Можно ли ускорить этот запрос?

    xpert13
    @xpert13
    Full Stack Developer
    По доброму, если вам нужна такая информация, то сумму для каждого пользователя необходимо считать в отдельной таблице (или таблице пользователей) и пересчитывать её каждый раз, когда добавляется новая запись в таблицу table. Тогда пересчет будет происходить для каждого пользователя отдельно и только тогда, когда что-то меняется.

    Альтернативный вариант, но менее эффективный - создать виртуальную таблицу для запроса:
    SELECT table.user_id, SUM(table.value) as value_sum FROM table GROUP BY table.user_id

    И уже из неё делать выборку с сортировкой и лимитом. Такую таблицу MySQL будет пересчитывать сама при каких-либо изменениях в таблице table, но я не уверен на сколько это будет быстро работать.
    Ответ написан
    1 комментарий
  • В чем основные отличия mySQL от Postgre?

    alekciy
    @alekciy
    Вёбных дел мастер
    Использую обе РСУБД. Предпочитаю Postgresql, хотя конечно начинал с MySQL. Из того, что на практике приводит к такому предпочтению:
    1) Отсутствие проблем на по сути пустом месте. Из последнего было, в одной базе есть таблицы с большим количеством текстовых полей. При вставке в одно из них чуть меньше 200 символов он отказывался ссылаясь на то, что переводите на динамические. И я значит должен начать курить тему движков мускула и выяснять, что мне оказывается нужна Barracuda. При той же InnoDb. Хочется спросить такого черта.
    Или вот еще вспомнил. При попытке записи в поле данных, больше чем это возможно для данной колонки он делает запись тупо обрезав лишнее. И проблему могут не заметить очень долго вплоть до момента когда подниматься из бэкапа поздно, там все уже битое.
    Или вот взять и сменить могут дефолтные значение переменных в рамках минорной версии. База после накатки апдейтов и ребута может просто не подняться. На хабре даже была статься по этому поводу.
    В общем множество подобных ситуаций после которых так и хочется воскликнуть "какого черта?!". Со слоном я не помню ни одной такой ситуации.
    2) RETURN во вставках/обновлениях. Можно получить в ответе любое поле такого запроса. И ни каких тебе танцев с LastInsertId.
    3) В последних версиях есть UPSERT которого очень не хватало.
    4) В целом более строгий подход и нет ощущение бардака.
    5) После запуска Postgres Pro появилась полностью руссифицированная документация. Помогает вкатиться в тему новичкам.

    Из минусов некоторое время было отсутствие адекватного UI клиента. Но после того, как стал использовать PhpStorm эта проблема была закрыта.
    Ответ написан
    1 комментарий
  • Можно ли и как делать запросы между БД PostgreSQL на разных серверах?

    ky0
    @ky0
    Миллиардер, филантроп, патологический лгун
    Можно, называется foreign wrapper.
    Ответ написан
    2 комментария
  • Вывести все объекты, в полях которых есть внешняя ссылка?

    sergey-gornostaev
    @sergey-gornostaev Куратор тега Django
    Седой и строгий
    В один запрос
    from django.db.models import Count
    
    Question.objects.annotate(choices_count=Count('choice')).filter(choices_count__gt=0)
    Ответ написан
    7 комментариев
  • Как правильно составить запрос для взятия первого значения из группы?

    Melkij
    @Melkij
    PostgreSQL DBA
    Ну а когда станет скучно перебирать всю таблицу - обращайтесь :-)

    Postgresql 9.4 и выше, выбор по известному диапазону дат через index scan по timestamp полю:
    select day, data 
    from generate_series('2017-12-10', '2017-12-12', interval '1 day') as day, 
    lateral (
        select data from tablename 
        where "timestamp" between day and day + interval '1 day' 
        order by "timestamp" desc limit 1
    ) ljd;


    Все дни из таблицы по индексу:
    with recursive t as (
    (select "timestamp"::date as day, data from tablename order by "timestamp" desc limit 1)
    union all
    select bpt.* from t, lateral (
    select "timestamp"::date as day, data from tablename where "timestamp" < t.day order by "timestamp" desc limit 1
    ) as bpt
    )
    select * from t;

    Используя loose index scan
    Ответ написан
    7 комментариев
  • Как правильно сделать фильтрацию по числу JSONB в PostgreSQL используя индекс?

    Melkij
    @Melkij
    PostgreSQL DBA
    Индекс возможно повесить функциональный:
    create index on tablename using btree(((features ->> 'capacity'::text)::integer));

    Соответственно предикат по этому же самому выражению получит возможность использовать этот индекс.

    Больше возможностей внятно индексировать jsonb для запросов на числовые диапазоны мне как-то не вспоминается. Сортировку по полю-то только btree и умеет из всех актуальных access method.

    Т.е. индекс используется, хотя в данном случае index срабатывает на price столбце? Тогда почему запрос отрабатывает быстро?

    Да, индекс используется - индекс по price. Потому что вы по нему сортируете. И планировщик опираясь на свою статистику надеется, что сможет быстро найти 25 строк читая строки в порядке требуемой сортировки по индексу и по пути проверять выкидывать неподходящие.
    Ответ написан
    2 комментария
  • Как преиодически отправлять данные от сервера клиенту через websocket?

    sergey-gornostaev
    @sergey-gornostaev Куратор тега Python
    Седой и строгий
    Насколько я понял, вы пытаетесь опрашивать базу данных и выводить изменения, а BSession.GetData() как раз данные из базы получает с помощью SQLAlchemy.

    Во-первых, обращение к базе синхронное и в моменты выполнения запросов будет ставить колом все установленные websocket-соединения. Использовать для решения это проблемы можно sqlalchemy_aio или SQLAlchemy+aiopg. А ещё лучше asyncpg без SQLAlchemy.

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

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

    async def consumer_handler(websocket, path):
        while True:
            message = await websocket.recv()
            # делаем что-нибудь с сообщением от клиента
    
    
    async def producer_handler(websocket, path):
        while True:
            data = await BSession.GetData()
            if data:
                await websocket.send(data)
    
    
    async def handler(websocket, path):
        consumer_task = asyncio.ensure_future(consumer_handler(websocket))
        producer_task = asyncio.ensure_future(producer_handler(websocket))
        done, pending = await asyncio.wait(
            [consumer_task, producer_task],
            return_when=asyncio.FIRST_COMPLETED,
        )
    
        for task in pending:
            task.cancel()
    
    
    loop = asyncio.get_event_loop()
    loop.run_until_complete(websockets.serve(handler, 'localhost', 8765))
    loop.run_forever()
    Ответ написан
    Комментировать