Помню, как в первый раз полез из Go в базу и минут сорок не понимал, почему всё работает.
Взял пример из документации, подставил свой DSN, запустил — ошибок нет. Обрадовался, пошёл писать дальше. А потом на первом же запросе выяснилось, что пароль я вписал от другой базы. И всё это время
sql.Open спокойно возвращал мне nil вместо ошибки.Оказалось, он туда и не ходил 😅
sql.Open не подключается. Он смотрит, что драйвер с таким именем зарегистрирован, разбирает строку подключения и отдаёт объект. Если в DSN синтаксическая опечатка — вот её покажут сразу. А жив ли сервер и верный ли пароль, на этом этапе не проверяет никто. В доке так и написано, «Open may just validate its arguments without creating a connection». Для настоящего похода в базу есть db.Ping().Меня это тогда здорово сбило, потому что в других языках открыл — значит открыл.
Ну и вдогонку, раз уж про это. То, что возвращает
Open, вообще не соединение, а пул. Он сам открывает их столько, сколько нужно, сам переиспользует, лезть к нему из горутин одновременно можно. Один такой на всё приложение.Видел код, где его звали в каждом хендлере. Вот это больно: пулы плодятся, база захлёбывается коннектами, а по коду всё выглядит опрятно.