Как вы обходитесь без ORM?

Всё время для связи с базой использовал ORM, очень редко приходилось писать SQL для выполнения запросов.

Тем не менее часто слышал, что у кого-то принято всё время писать чистый SQL, без использования ORM. Если вы это делаете, можете привести пример кода? Как вы потом работаете со строками, просто как со словарями? Как вы защищаетесь от опечаток в названии столбцов таблицы? Даже для самых простых запросов, например, `SELECT ... FROM table WHERE id = 1`, вы всё время пишете такой длинный запрос?

Буду благодарен за разъяснения о том, как это работает у вас.
  • Вопрос задан
  • 2886 просмотров
Решения вопроса 1
dimonchik2013
@dimonchik2013
non progredi est regredi
зависит от языка и размера проекта

язык - Питон - сам Бог велел (Алхимия или Джанго тем более)
язык - Go - без сахара какая разница что писать: все равно и приведение будет и многобукв будет

а размер проекта - очень просто - называется "в два раза",
это усредненно (кажется, на Хабре была статья с цифрами 120-500%) ,
пока "в два раза" не критично - можно довольствоваться и ОРМ
Ответ написан
Пригласить эксперта
Ответы на вопрос 5
sim3x
@sim3x
Как вы потом работаете со строками, просто как со словарями?
большую часть задач такого плана нужно свалить на субд. Когда остается выборка на 10-100-1к елементов - перебирается как словарь или список

Как вы защищаетесь от опечаток в названии столбцов таблицы?
тесты завалятся, иде подсветит, иде подтянет константы из кода или из БД

Даже для самых простых запросов, например, `SELECT ... FROM table WHERE id = 1`, вы всё время пишете такой длинный запрос?
если такой запрос встречается три раза он выносится и потом вызывается, как функция
Запрос "длинный", когда он не помещается на один екран или его требуется дробить, чтоб понять логику его исполнения

Думать об отказе от орм, вам как разрабу нужно после очень большого опыта работы на позициях архитектора, при наличии команды, которая вам не сильно уступает, те в очень редчих случаях
Ответ написан
Комментировать
LaRN
@LaRN
Senior Developer
Если нагрузка на БД не большая и структура БД простая, то ORM подойдёт. Но если много таблиц большого размера(миллионы записей) и требуется строить отчетность, то ORM уже не потянет.
Нужно руками строить запросы и анализировать план выполнения, чтобы выжать максимум. Обратная сторона - если нужно поддерживать несколько платформ, то писать запросы придётся для каждой платформы с учетом особенностей синтаксиса.
Ответ написан
Комментировать
devalone
@devalone
̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻
Мне больше нравится, когда можно и ORM и вручную запросы писать. В python, например, есть отличная либа sqlalchemy, там можно использовать orm, sqlalchemy core(что-то среднее) и писать запросы вручную(но sqlalchemy синхронный и это минус). Обычно вручную пишут для оптимизации или каких-то не тривиальных штук, вроде построения гистограммы.
Если вы это делаете, можете привести пример кода?

users = await connection.fetch('''
                            SELECT * FROM core_user
                            WHERE is_updated = true and last_update_timestamp <= $1 - updating_period LIMIT $2
                            ''', int(time.time()), settings.BOT_CONCURRENT_TASKS)

Как вы потом работаете со строками, просто как со словарями?

Да
user['password']
, есть либы, которые позволяют обращаться так
user.password

Как вы защищаетесь от опечаток в названии столбцов таблицы?

Так ошибка ж будет.
Или вот пример, не представляю, как сделать с ORM
sql_request = '''
        WITH stats AS (
            SELECT MIN(:field_name) as min_value, MAX(:field_name) as max_value
            FROM :table_name
        )
        SELECT 
            width_bucket(:field_name, min_value, max_value, :window_size) as bucket,
            MIN(:field_name) as x,
            COUNT(*) AS y
        FROM 
            :table_name, stats
        GROUP BY
            bucket
        ORDER BY
            bucket;
    '''.replace(':field_name', field_name)\
        .replace(':table_name', table_name)\
        .replace(':window_size', str(window_size))

items = await asyncpgsa.pg.fetch(sql_request, *sql_arguments)

return [PostgreSQLSerializer(['x', 'y']).serialize(item) for item in items if item['y'] != 0]
Ответ написан
Комментировать
xmoonlight
@xmoonlight
https://sitecoder.blogspot.com
1. Один php-класс - это одна роль системы для работы с базой.
2. При инициализации класс получает свой ACL: все таблицы, поля таблиц, с которыми он может работать и с какими доступами к каждому из этих объектов.
3. Запрос пишу в любом инструменте работы с базой данных и тестирую (query).
4. Копирую и заменяю нужные мне части на подстановочные переменные:
$sql = 'SELECT * FROM [user] WHERE id=[$id:numeric] OR user=[$id:string] LIMIT 1';
5. После прогонки через функцию проверки переменных, доступа, экранирования и составления реального запроса к базе, происходит его исполнение.
Ответ написан
Комментировать
solotony
@solotony
покоряю пик Балмера
Все зависит от запросов и от потребности в оптимизации.

когда в перспективе тяжелый запрос на фронт который будут делать 10 клиентов одновременно, я буду делать его на чистом SQL (а сам фронт напишу на "С")

а если вы пишете бэкенд - до пусть там пол-часа считает - вам то что ?
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы