NJ Soft

Заметка об отладке запросов в Doctrine2

Заметка об отладке запросов в Doctrine2

Эта заметка поможет вам найти ошибку в запросах сформированных с помощью библиотеки doctrine2 dbal используемой для языка программирования PHP. Это популярная и качественная библиотека для разработки запросов к базе данных , которая предоставляет удобный API для работы с БД.

В данной заметке речь пойдёт о версии библиотеки doctrine/dbal 2.13.1 и 3.2.

При работе с базой через «query builder» библиотека формирует запрос на «своём языке» этот язык называется DQL (doctrine query lanbuage) который используется в dbal (DataBase Abstraction Layer) и он поддерживает работу с популярными и востребованными SQL базами данных. Затем сфомированный DQL-запрос проверяется на корректность и после этого конвертируется в SQL-запрос конкретной базы данных.

Из этого описания следует что возможны 2 места возникновения ошибки:

  1. Ошибка в DQL-запросе
  2. Ошибка в SQL-запросе

1. Ошибка в DQL-запросе

При отладке DQL-запроса логирования внутри сервера БД не поможет, потому что запрос не будет отправлен в БД из за ошибки. Для ошибок в DQL-запросах библиотека формирует исключительную ошибку (Exception) с типом (классом) Doctrine\ORM\Query\QueryException.

Сообщение такой ошибки будет содержать текст
[Syntax Error] line {строка}, col {колонка}: Error: {ошибка}

В этом сообщении {строка} и {колонка} будут указывать место в DBAL- запросе где происходит ошибка, а {ошибка} выводит текст ошибки. Например:
[Syntax Error] line 0, col 7: Error: Excepcted T_OPEN_PARETHNESS...

Такая ошибка говорит о том что внутри сформированного запроса встречается оператор или ключевое слово не поддерживаемое DBAL языком.

Чтобы понять в чём ошибка, нужно получить DQL-запрос, для этого можно воспользоваться методом getDQL — и нужно переместиться к указанным координатам ошибки line, col. Если вы используете phpstorm, то можно воспользоваться функцией Naviate → Go to line:column (хоткей для этого Ctrl+G) и ввести 0:7 и вы попадёте в место где произошла ошибка. Проанализируйте это место и исправьте условия формирования этого места.

Помните что ошибки с текстом [Syntax error] выдают координаты места ошибки. После этого они становятся не такими страшными :)

2. Ошибка в SQL-запросе

После того как DQL-запрос пройдёт проверку он будет сконвертирован в SQL и отправлен в базу данных. После того как запрос отправлен — база данных может вернуть ответ с ошибкой, который возник вследствие неверно сформированного SQL-запроса. В таких случаях библиотека doctrine2 dbal вернёт исключительную ошибку, которая будет зависеть от используемой базы данных, а точнее от используемого «драйвера базы данных» (код, который описывает логику работу с конкретной базой данных).

Такие ошибки чаще всего содержать сообщение начинающееся с
[SQLSTATE {код-состояния}] An exception occured...

Чтобы отладить эти ошибки можно воспользоваться получением SQL запроса с помощью метода getSQL и проанализировать его. Также можно получить запрос на самом сервере БД, включив логирование запросов.

Где ещё посмотреть запросы?

Если использовать библиотеку совместно с фреймворком symfony, то в режиме отладки для фреймворка включёно логирование всех ошибок в dev.log (в зависимости от того как настроена ротация логов). В этом файле лога ошибки DQL-запросов сохраняются с полным текстом запроса. Поэтому можно не править код вызывая метод getDQL, а просто посмотреть в лог и взять оттуда текст запроса, а затем в нём прыгнуть в координаты line:col в вашем текстовом редакторе. Только DQL пишет line = 0. Нужно иметь ввиду что в некоторых текстовых редакторах (в большинстве) нумерация строк начинается с 1. Т.е если DQL пишет line: 0, col: 1, то прыгать надо в 0:1 адрес.

  • Приглашаем подписаться на наши страницы в социальных сетях:

    Telegram
    Вконтакте
Все статьи →

Есть вопросы по статье?

Отправьте нам сообщение, и мы свяжемся с вами, чтобы всё обсудить

Приглашаем к сотрудничеству
130+
завершённых проектов
20+ лет
помогаем клиентам расти
127473, Москва, улица Селезневская, дом 32
Заполните форму и мы свяжемся с вами в ближайшее время!
Согласен с обработкой моих персональных данных
в соответствии с политикой конфиденциальности
127473, Россия, Москва, улица Селезневская, дом 32, офис 302
+7 (495) 477-60-74