Я на ORM и генераторы запросов смотрю как на хорошую подсказку IDE и компилятору, что у нас из базы возвращается не какой-то сферический ResultSet, а некоторый объект с вполне определёнными полями и методами.
Это отсекает такой класс ошибок, как написать запрос, отладить его в IDE для БД (она как правило отдельная), перенести его в код и потом с удивлением ловить ошибки в рантайме, из-за того, что поле в результате или называется не как надо, или просто забыли добавить поле в выборку.
Хорошие IDE/ORM ещё могут слазить в базу за схемой, проверить имена маппингов, сгенерить миграции итд.
Ещё веселее становится, когда надо динамически собирать where и делать join у запроса в зависимости от входных параметров — собирать запросы конкатенацией или шаблонами довольно утомительное и багообразующее занятие.
Я очень не уверен, что все СУБД поддерживают несколько транзакций в одном соединении, так что возможность открывать по транзакции на курсор фича попросту нереализуемая в большинстве реализаций и мешающая распространению стандарта.
Стандарт — это всегда какое-то общее подмножество того, что есть на рынке.
На самом деле мы сейчас гадаем на кофейной гуще, пытаясь понять, что двигало авторами спеки. Вероятнее всего уже до PEP уже существовала какая-то реализация, где всё ограничивалось фичами конкретной СУБД, и которую почти без изменений втащили в стандарт.
Судя по автору PEP, уши растут из драйвера mxODBC.
я вот и говорю, что в одной транзакции может быть теоретически открыто больше одного объекта курсора в зависимости от СУБД и это нормально. Транзакция при этом будет одна, общая.
Допустим, мы хотим почитать из нескольких табличек параллельно так, чтобы данные из обеих были консистентны. Допустим мы делаем джойн или какую-то сверку данных из двух больших таблиц на клиенте.
Нужно открыть транзакцию режиме в SNAPSHOT ISOLATION и читать с помощью serverside cursor кусочками, потом оба курсора закрыть и выбросить.
в том-то и запутанность ситуации, что PEP утверждает, что в этой переменной уровня модуля должен содержаться используемый модулем paramstyle, но ни слова не говорит, можно или нельзя его изменить, и если можно, то как это делать, а также не накладывает ограничений на те варианты paramstyle, который реализовать обязательно.
PEP-249 ничего по этому поводу не говорит, но я понимаю, почему авторы вытащили курсоры в отдельную сущность — их точно даже может существовать больше одного на соединение в некоторых БД.
MySQLdb и psycopg2 емнип делают close всем открытым курсорам этого соединения при commit.
Потому что существуют СУБД, умеющие несколько курсоров в одной транзакции. Например может вернуться несколько курсоров как результат выполнения хранимой процедуры у какого-нибудь Oracle.
Но при этом авторы спецификации не стали заморачиваться и объединили сущность транзакции и соединения, чем обломали кайф любителям firebird, у них общепринятая практика — открыть одну длинную читающую транзакцию в read committed и записи делать короткими пишущими транзакциями внутри одного и того же соединения.
На самом деле мне тоже не нравится подобная ситуация — можно закрыть транзакцию, сломав вдребезги напополам ещё не закрытые и недочитанные курсоры.
а это уже разное от драйвера к драйверу, чем меня спецификация db-api2 изрядно расстраивает.
Очень не хватает четкой спеки на параметры, специфицированного autocommit в стандарте, serverside-курсоров,
dict или объекты во всех драйверах тоже реализованы, но по-разному и это печально.
Нет connection pooling и асинхронщины, что встаёт костью в горле, когда скрещиваешь это с каким-нибудь asyncio (я в своё время пытался скрещивать с twisted, примерно такого же порядка проблемы).
Пришло время описывать db api3 =)
для грепа исходников есть няшные ack (пакет ack-grep в дебиане) и ag. Они не лазят во всякие .git, .svn, бинарники и хорошо настроены по дефолту для подсветки итд.
добрый день.
есть 2 вопроса:
1. не знаете ли, каким образом можно оценить время наработки на отказ у ламп? У меня умерли 3 лампы одного производителя друг за другом в течение недели примерно через год службы.
2. Также некоторые лампы ощутимо ослабевают по светимости по мере службы, причем неравномерно. Это я наблюдал на примере каких-то noname китайских mr-16 в ванной.
нет ли каких-то методик, которыми можно это выявить?
У вас что-то не так с архитектурой. Это задача для самой базы, а не для стороннего скрипта.
Может быть да, а может быть нет. Далеко не всё можно объяснить "кривой архитектурой". Допустим, вам надо перенести юзера/кусок данных на котором воспроизводится баг из основной БД в тестовую. Или например сериализовать маленький кусочек данных, чтоб потом подложить их в качестве фикстур юнит-тестам.
Это удобно. Также для уже живущих проектов нельзя просто так взять и выкинуть существующим mysql/postgresql etc, чтоб впилить туда базу с автоматическим шардингом — это может просто угробить проект.
Боже ты мой, тащить "кусок говна" на руби, когда у нас и так есть "кусок говна" на nodejs? Появляется ещё целых 2 лишних сущности (redis и сам менеджер задач). Не находите это перебором во многих случаях? Мне всего-то надо раз в час подсасывать csv-шку или выливать отчётец в шару. Тащить в проект ещё 2 сущности, которые надо мониторить для этого — нет, спасибо. А если этот проект ещё и тиражировать требуется? Затраты на администрирование растут ещё быстрее. Чем меньше разнородных частей в архитектуре, и чем проще каждая часть — тем лучше.
Я в таком случае вкручиваю ручки под суперадмином во фронтенд и дергаю их хоть с Багам через веб-интерфейс.
Это если вы заранее знаете, какой отчётец надо сделать. А если нет? И когда вы дёргаете построение отчёта через веб, вы надолго занимаете воркер, который нужен веб-части. Двухчасовой отчёт просто отвалится по таймауту. Админку на отдельных мощностях поднимать и держать?
Часто проще наговнокодить на коленке какой-то скрипт, потом согласовать 2-3 раза с заказчиком отчёта, и лишь потом закатать его в джоб, запускаемый по расписанию, да сдать админам.
Просто если сначала думать, а потом делать — скрипты на js писать не придется.
Тут есть проблема. Рынок разработчиков конечен. В небольших городах он ещё более конечен. Можно конечно набирать разработчиков, умеющих в много разных языков подряд, но тогда они будут дороже. За тотальный js говорило:
V8 — это быстрый и довольно качественный рантайм, нетребовательный к ресурсам. (если сравнивать с python/ruby и подобными)
быстрое прототипирование
относительная немногословность
достаточное количество библиотек.
достаточное количество грабей в гугле, благодаря большому комьюнити.
Можно валить на одного разработчика и фронтенд и бекенд части какой-то фичи. Тимлид потом побъёт палкой на код-ревью и в итоге получится более-менее рабочее. И можно будет катить фичи, даже если кто-то заболеет / уйдёт в отпуск.
снижение требований к разработчику. Народ, когда читает вакансии меньше пугается и идёт собеседоваться.
Против:
Язык так себе. Частично купируется ES6/Typescript, драконовски настроенным линтером, и тотальными юнит-тестами.
Библиотек хоть и много, но много из них весьма посредственного качества. То и дело ломаются. Чинить через CI и битьём по рукам, чтоб не тащили всё подряд в проект.
dependency hell.
В советах в гугле МНОГО говнокода, всё равно требуется головой думать (3 раза ха).
Есть плюсы, есть минусы. Плюсы пока перевешивают.
// Правда какие-то инструменты мы всё равно пишем на питоне — если есть требование к минимизации зависимостей и нет завязки на модели БД.
Про фронтенд согласен, всё просто. Сделал gulp build и потом вывалил dist в каталог со статикой.
С полным приложением всё немного интереснее.
В итоге мы и собираем docker-контейнер, чтобы ни от чего не зависеть.
Если вам надо, например, поработать с oracle, то:
1) на сервере обязаны стоять клиентские библиотеки.
2) вы обязаны собрать биндинги ровно под эти версии библиотек и с бинарно совместимыми версиями других пакетов.
Это не вина npm и ноды. Это дополнительное требование, которое должно соблюдаться.
Решения:
1) тащим на продакшен компилятор и там собираем всё. У админа болит голова и плохо спится, потому что куча всякой дряни на сервере и что-то может не собраться в самый ответственный момент.
2) Собираем отдельно и копируем node_modules, то есть риск, что версии бинарей могут не сойтись и приложение на продакшен сломается (это почти ок)/ будет вести себя странно (а вот это плохо). Т.е. отсюда растёт требования поддержания билд-среды в идеальном соответствии продакшену — тоже потенциальная головная боль админа.
3) докер-контейнер в котором всё собирается и из которого потом вышвырнуто всё лишнее. Этим путём мы и пошли.
Я знаю как минимум один случай, когда логично использовать тот же язык программирования, на котором реализовано основное приложение -если вам требуется работать с теми же моделями данных.
Примеры:
Нужен ручной/по расписанию перенос пользователя из одного инстанса БД в другую.
Нужен тяжёлый фоновый расчёт, выполняемый по расписанию.
Нужны какие-то разовые наколеночные отчёты по данным БД.
И то и другое — самые настоящие скрипты. И в гробу я, и как разработчик, и как админ, видел поддерживать две имплементации моделей с валидацией на двух разных языках, просто потому что "не хочется тащить всякое говно на сервер".
Да, я в целом согласен, что использовать js для написания консольных инструментов не очень удобно, потому что стандартная библиотека откровенно бедная => требуется тащить много стороннего кода, есть проблемы в языке => добавляются классы возможных ошибок (без тестов на js писать невозможно совсем).
Но я бы ни за что в жизни не выбрал бы баш/другой язык для скриптов ребалансировки шардов, импорта / экспорта данных итд.
Билд-окружение обязано иметь одну особенность — нужно, чтобы оно по версиям пакетов/abi совпадало с продакшеном. Это не всегда возможно (при тиражировании ПО, например) и несёт в себе некоторый риск.
Мы-то собираем вообще так, чтоб потом не болела голова от несовпадения окружений. Я даже небольшой костыль на питоне для этого написал.
yarn появился без году неделя, и я на него ещё не смотрел.
И проблема не в скорости де.
Проблемы установки npm install и подобными инструментами в следующем:
большинство транзитивных зависимостей нефиксированы. т.е. на прод внезапно может приехать новая версия пакета в транзитивных зависимостях, которая всё сломает.
часто требуется выполнить некоторый набор gulp/grunt-тасок для сборки (минификация итп задачи). Не хочется тащить devDependences на продакшн ради этого.
это не работает, если отсутствует интернет у килента.
это может не работать, если требуется собирать сишные биндинги. На продакшне требуется компилятор и заголовочные файлы.
среда на продакшене потенциально нестабильна — может приехать новый libc и всё сломать (но это уже очень маловероятно).
из прошлых пунктов следует невоспроизводимость билда — на проде может получиться другое сочетание, нежели в среде разработки и тестинге.
Вышеприведённые пункты можно решать разными способами.
Мы для наших проектов выбрали сборку докер-образа из которого потом выкидывается всё лишнее и делается его компактизация через docker export | docker import. Получается не зависящий ни от чего неизменяемый кусок файловой системы, на которой есть только то, что реально нужно для работы приложения.
У меня к вам вопрос — yarn может решить какие-то проблемы из этих и как?
Не самая плохая замена — это решает проблему того, что может сломаться пакет в глубине, но совершенно не помогает в случае отсутствия интернета в продакшен системе и необходимости устанавливать что-либо из закрытых репозиториев — растаскивать деплой-ключи в нашем случае неприемлемо.
Также shrinkwrap не решает проблему, если нужно собирать биндинги к сишным библиотекам — на продакшене неожиданно становятся нужны компилятор, заголовочные файлы итд.
Мне очень нравится spread operator — благодаря ему, хорошо уменьшилась длина строчек в тестах, когда требуется вызвать одну и ту же функцию с похожим набором параметров. Можно зафиксировать префикс и дальше применять его к нужной функции.
почему шелл-скрипт, а не CGI, скажем, которые, мог иметь ввиду автор жирного наброса комментария выше, и возможно даже автор поста?
я просто прицепился ко второму вашему предложению и отметил, что сравнивать реализации express и SimpleHTTPServer некорректно.
С тем, что на js ужасно неудобно писать консольные утилиты из-за ужасно бедной стандартной библиотеки и отсутствия в стандартной поставке дистрибутивов, я не спорю.
Я на ORM и генераторы запросов смотрю как на хорошую подсказку IDE и компилятору, что у нас из базы возвращается не какой-то сферический ResultSet, а некоторый объект с вполне определёнными полями и методами.
Это отсекает такой класс ошибок, как написать запрос, отладить его в IDE для БД (она как правило отдельная), перенести его в код и потом с удивлением ловить ошибки в рантайме, из-за того, что поле в результате или называется не как надо, или просто забыли добавить поле в выборку.
Хорошие IDE/ORM ещё могут слазить в базу за схемой, проверить имена маппингов, сгенерить миграции итд.
Ещё веселее становится, когда надо динамически собирать where и делать join у запроса в зависимости от входных параметров — собирать запросы конкатенацией или шаблонами довольно утомительное и багообразующее занятие.
Я очень не уверен, что все СУБД поддерживают несколько транзакций в одном соединении, так что возможность открывать по транзакции на курсор фича попросту нереализуемая в большинстве реализаций и мешающая распространению стандарта.
Стандарт — это всегда какое-то общее подмножество того, что есть на рынке.
На самом деле мы сейчас гадаем на кофейной гуще, пытаясь понять, что двигало авторами спеки. Вероятнее всего уже до PEP уже существовала какая-то реализация, где всё ограничивалось фичами конкретной СУБД, и которую почти без изменений втащили в стандарт.
Судя по автору PEP, уши растут из драйвера mxODBC.
Ёжик оказался не прав.
https://habrahabr.ru/post/321510/#comment_10074610
я вот и говорю, что в одной транзакции может быть теоретически открыто больше одного объекта курсора в зависимости от СУБД и это нормально. Транзакция при этом будет одна, общая.
Допустим, мы хотим почитать из нескольких табличек параллельно так, чтобы данные из обеих были консистентны. Допустим мы делаем джойн или какую-то сверку данных из двух больших таблиц на клиенте.
Нужно открыть транзакцию режиме в SNAPSHOT ISOLATION и читать с помощью serverside cursor кусочками, потом оба курсора закрыть и выбросить.
в том-то и запутанность ситуации, что PEP утверждает, что в этой переменной уровня модуля должен содержаться используемый модулем paramstyle, но ни слова не говорит, можно или нельзя его изменить, и если можно, то как это делать, а также не накладывает ограничений на те варианты paramstyle, который реализовать обязательно.
и да, я не прав, про то, что это можно нормально настраивать. Там на самом деле обычный pyformat.
Автор вкатал тупой if в этом месте и подстановку в запрос без всякой защиты от инъекций https://github.com/farcepest/MySQLdb1/blob/master/MySQLdb/cursors.py#L183
PEP-249 ничего по этому поводу не говорит, но я понимаю, почему авторы вытащили курсоры в отдельную сущность — их точно даже может существовать больше одного на соединение в некоторых БД.
MySQLdb и psycopg2 емнип делают close всем открытым курсорам этого соединения при commit.
Потому что существуют СУБД, умеющие несколько курсоров в одной транзакции. Например может вернуться несколько курсоров как результат выполнения хранимой процедуры у какого-нибудь Oracle.
Но при этом авторы спецификации не стали заморачиваться и объединили сущность транзакции и соединения, чем обломали кайф любителям firebird, у них общепринятая практика — открыть одну длинную читающую транзакцию в read committed и записи делать короткими пишущими транзакциями внутри одного и того же соединения.
На самом деле мне тоже не нравится подобная ситуация — можно закрыть транзакцию, сломав вдребезги напополам ещё не закрытые и недочитанные курсоры.
это должно быть можно настраивать через paramstyle
а это уже разное от драйвера к драйверу, чем меня спецификация db-api2 изрядно расстраивает.
Очень не хватает четкой спеки на параметры, специфицированного autocommit в стандарте, serverside-курсоров,
dict или объекты во всех драйверах тоже реализованы, но по-разному и это печально.
Нет connection pooling и асинхронщины, что встаёт костью в горле, когда скрещиваешь это с каким-нибудь asyncio (я в своё время пытался скрещивать с twisted, примерно такого же порядка проблемы).
Пришло время описывать db api3 =)
для грепа исходников есть няшные ack (пакет ack-grep в дебиане) и ag. Они не лазят во всякие .git, .svn, бинарники и хорошо настроены по дефолту для подсветки итд.
есть 2 вопроса:
1. не знаете ли, каким образом можно оценить время наработки на отказ у ламп? У меня умерли 3 лампы одного производителя друг за другом в течение недели примерно через год службы.
2. Также некоторые лампы ощутимо ослабевают по светимости по мере службы, причем неравномерно. Это я наблюдал на примере каких-то noname китайских mr-16 в ванной.
нет ли каких-то методик, которыми можно это выявить?
Может быть да, а может быть нет. Далеко не всё можно объяснить "кривой архитектурой". Допустим, вам надо перенести юзера/кусок данных на котором воспроизводится баг из основной БД в тестовую. Или например сериализовать маленький кусочек данных, чтоб потом подложить их в качестве фикстур юнит-тестам.
Это удобно. Также для уже живущих проектов нельзя просто так взять и выкинуть существующим mysql/postgresql etc, чтоб впилить туда базу с автоматическим шардингом — это может просто угробить проект.
Боже ты мой, тащить "кусок говна" на руби, когда у нас и так есть "кусок говна" на nodejs? Появляется ещё целых 2 лишних сущности (redis и сам менеджер задач). Не находите это перебором во многих случаях? Мне всего-то надо раз в час подсасывать csv-шку или выливать отчётец в шару. Тащить в проект ещё 2 сущности, которые надо мониторить для этого — нет, спасибо. А если этот проект ещё и тиражировать требуется? Затраты на администрирование растут ещё быстрее. Чем меньше разнородных частей в архитектуре, и чем проще каждая часть — тем лучше.
Это если вы заранее знаете, какой отчётец надо сделать. А если нет? И когда вы дёргаете построение отчёта через веб, вы надолго занимаете воркер, который нужен веб-части. Двухчасовой отчёт просто отвалится по таймауту. Админку на отдельных мощностях поднимать и держать?
Часто проще наговнокодить на коленке какой-то скрипт, потом согласовать 2-3 раза с заказчиком отчёта, и лишь потом закатать его в джоб, запускаемый по расписанию, да сдать админам.
Тут есть проблема. Рынок разработчиков конечен. В небольших городах он ещё более конечен. Можно конечно набирать разработчиков, умеющих в много разных языков подряд, но тогда они будут дороже. За тотальный js говорило:
Против:
Есть плюсы, есть минусы. Плюсы пока перевешивают.
// Правда какие-то инструменты мы всё равно пишем на питоне — если есть требование к минимизации зависимостей и нет завязки на модели БД.
Про фронтенд согласен, всё просто. Сделал gulp build и потом вывалил dist в каталог со статикой.
С полным приложением всё немного интереснее.
В итоге мы и собираем docker-контейнер, чтобы ни от чего не зависеть.
Если вам надо, например, поработать с oracle, то:
1) на сервере обязаны стоять клиентские библиотеки.
2) вы обязаны собрать биндинги ровно под эти версии библиотек и с бинарно совместимыми версиями других пакетов.
Это не вина npm и ноды. Это дополнительное требование, которое должно соблюдаться.
Решения:
1) тащим на продакшен компилятор и там собираем всё. У админа болит голова и плохо спится, потому что куча всякой дряни на сервере и что-то может не собраться в самый ответственный момент.
2) Собираем отдельно и копируем node_modules, то есть риск, что версии бинарей могут не сойтись и приложение на продакшен сломается (это почти ок)/ будет вести себя странно (а вот это плохо). Т.е. отсюда растёт требования поддержания билд-среды в идеальном соответствии продакшену — тоже потенциальная головная боль админа.
3) докер-контейнер в котором всё собирается и из которого потом вышвырнуто всё лишнее. Этим путём мы и пошли.
Я знаю как минимум один случай, когда логично использовать тот же язык программирования, на котором реализовано основное приложение -если вам требуется работать с теми же моделями данных.
Примеры:
И то и другое — самые настоящие скрипты. И в гробу я, и как разработчик, и как админ, видел поддерживать две имплементации моделей с валидацией на двух разных языках, просто потому что "не хочется тащить всякое говно на сервер".
Да, я в целом согласен, что использовать js для написания консольных инструментов не очень удобно, потому что стандартная библиотека откровенно бедная => требуется тащить много стороннего кода, есть проблемы в языке => добавляются классы возможных ошибок (без тестов на js писать невозможно совсем).
Но я бы ни за что в жизни не выбрал бы баш/другой язык для скриптов ребалансировки шардов, импорта / экспорта данных итд.
Билд-окружение обязано иметь одну особенность — нужно, чтобы оно по версиям пакетов/abi совпадало с продакшеном. Это не всегда возможно (при тиражировании ПО, например) и несёт в себе некоторый риск.
Мы-то собираем вообще так, чтоб потом не болела голова от несовпадения окружений. Я даже небольшой костыль на питоне для этого написал.
yarn появился без году неделя, и я на него ещё не смотрел.
И проблема не в скорости де.
Проблемы установки npm install и подобными инструментами в следующем:
Вышеприведённые пункты можно решать разными способами.
Мы для наших проектов выбрали сборку докер-образа из которого потом выкидывается всё лишнее и делается его компактизация через
docker export | docker import. Получается не зависящий ни от чего неизменяемый кусок файловой системы, на которой есть только то, что реально нужно для работы приложения.У меня к вам вопрос — yarn может решить какие-то проблемы из этих и как?
Не самая плохая замена — это решает проблему того, что может сломаться пакет в глубине, но совершенно не помогает в случае отсутствия интернета в продакшен системе и необходимости устанавливать что-либо из закрытых репозиториев — растаскивать деплой-ключи в нашем случае неприемлемо.
Также shrinkwrap не решает проблему, если нужно собирать биндинги к сишным библиотекам — на продакшене неожиданно становятся нужны компилятор, заголовочные файлы итд.
и это тоже, насколько я понимаю лишь shallow-copy =(
Мне очень нравится spread operator — благодаря ему, хорошо уменьшилась длина строчек в тестах, когда требуется вызвать одну и ту же функцию с похожим набором параметров. Можно зафиксировать префикс и дальше применять его к нужной функции.
Правда мы пока сидим на 5.10 и не можем использовать эмуляцию именованных аргументов.
А так был бы почти python.
Могу сказать, что это очень сильно улучшает читаемость кода.
почему шелл-скрипт, а не CGI, скажем, которые, мог иметь ввиду автор
жирного набросакомментария выше, и возможно даже автор поста?я просто прицепился ко второму вашему предложению и отметил, что сравнивать реализации express и SimpleHTTPServer некорректно.
С тем, что на js ужасно неудобно писать консольные утилиты из-за ужасно бедной стандартной библиотеки и отсутствия в стандартной поставке дистрибутивов, я не спорю.