Pull to refresh

Comments 9

Почему я должен предпочесть ваш способ по сравнению с jinja?
Ну а если надо играться с SQL, то точно следует предпочесть SQLAlchemy, он гарантирует безопасность и валидность результата.
Во-первых, ни jinja, ни SQLAlchemy не подойдут, если заменить Python на любой другой язык программирования. Во-вторых, всё описанное в статье можно делать и с jinja, просто для примера взят mustache. Такое ощущение, что вы не читали статью.
не совсем понятна причина использования мусташи, если logic-less. Это же могут быть текстовые файлы, которые далее sodergimoe_faila.format(**kwargs)

В моем проекте я использую модельку шаблонов, для хранения их в базе, и тогда заготовки для будущих «артефактов» удобно править онлайн.

Я не пропагандирую какой-то конкретный шаблонизатор, но да, склоняюсь к минимизации логики внутри шаблонов (форматтеры и предикаты по спискам — ОК, выполнение произвольного кода — не ОК). Шаблонизирование через format хорошо, если в модели нет массивов и условий (то есть для ряда случаев — вполне себе метод).


Ну и скорее статья дискутирует с методом, когда подобные артефакты создаются путем конкатенации строчек внутри кода. Такой подход я встречал неоднократно (особенно почему-то любят так мучать SQL). Результат — очень мутный код.


Для сравнения — добавил в гитхабе в template_3.py класс, который формирует SQL путем конкатенации строк по той же модельке. Довольно мутная штука в плане наглядности:


class SqlAntipattern(object):
    def render(self, m):
        if m["typeList"]:
            return self.render_typelist(m)
        if m["typeCountGroupBy"]:
            return self.render_groupby(m)

        raise Exception("Unknown query type")

    def render_where(self, m):
        sql = "WHERE "

        def eqtion(w):
            return "{}={}{}{}".format(
                w["field"],
                "'" if "quot" in w else "",
                w["eq_val"],
                "'" if "quot" in w else "")

        wheres = [eqtion(w) for w in m["where"]]
        sql += ", ".join(wheres)
        return sql + " "

    def render_orderby(self, m):
        return "ORDER BY " + m["orderBy"]

    def render_typelist(self, m):
        sql = "SELECT * FROM " + m["tableName"] + " "
        if "hasWhere" in m:
            sql += self.render_where(m)

        if "orderBy" in m:
            sql += self.render_orderby(m)

        if "limit" in m:
            sql += " LIMIT " + m["limit"]

        return sql

    def render_groupby(self, m):
        sql = "SELECT " + m["groupColumn"]
        sql += ", COUNT(*) FROM " + m["tableName"] + " "
        sql += " GROUP BY " + m["groupColumn"]

        return sql
хмм. Код выглядит очень странно.
например зачем так сложно, можно же без конкатенаций строк сделать:
render_where
def render_where(self, m):
        returned_template = 'WHERE {my_where} '.format
        whered_template = "{field}={separator}{eq_val}{separator}".format
        wheres = ", ".join(whered_template(separator="'" if 'quot' in w else '', **w) for w in m["where"]))
        return returned_template(my_where=wheres)

render_groupby
def render_groupby(self, m):
    returned_template = 'SELECT {groupColumn}, COUNT(*) FROM {tableName} GROUP BY {groupColumn}'.format
    return returned_template(**m)


Хотя это все от лукавого. Наличие подобного кода может сообщать об ошибке в архитектуре приложения.

P.s. Я люблю нагружать текстовыми обработками запросы к базе. На это у меня есть личные причины. Результат — очень прозрачный код.
Как пример текстовых артефактов: конфиги SIP-телефонов. У меня сервер провижна так работает — из общего набора данных генерится конфиг по шаблону с заполненными данными habr.com/ru/post/445350 имхо, вполне очевидная идея ))
Мы видим в шаблоне, что шапка документа для заказов в Урюпинске отличается от других городов.


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

В шаблоне должно быть что то вроде:
«Если есть дополнтельное примечание, то вот тут его выводим»

А что это конкретно за примечание и для кого оно Урюпинска или для Сызрани там — не шаблон должен это решать.

Согласен про бизнес-логику, но в этом месте статьи я изящно (смайлик) показал способ быстро захардкодить странное. А за странным бизнес иногда прибегает в пятницу вечером со словами что "все забыли, сорян, но в субботу оно должно работать, потому что Урюпинск с утра будет на федеральных каналах". Дописывать ядро бизнес-логики и выкатывать на прод в пятницу не всегда хочется, поэтому можно например вот так, по-простому. С одновременным постом в трекер задачи на техдолг.

(здесь был ответ на комментарий про бизнес-логику, который потом перенес в правильную ветку)

Sign up to leave a comment.

Articles