Странное поведение с именами столбцов в верхнем регистре в Doctrine 1.1, приводящее к исключению

У меня проблема с регистром имени столбца в Doctrine версии 1.1.0.

У меня есть запись (сущность) с этим определением:

abstract class BaseProductsXsell extends Doctrine_Record
{
    public function setTableDefinition()
    {
        $this->setTableName('products_xsell');
        $this->hasColumn('ID', 'integer', 4, array('type' => 'integer', 'length' => 4, 'primary' => true, 'autoincrement' => true));
        $this->hasColumn('products_id', 'integer', 4, array('type' => 'integer', 'length' => 4, 'unsigned' => 1, 'default' => '1', 'notnull' => true));
        // and so on...
    }
}

В таблице базы данных MySQL имя столбца «ID» также указано в верхнем регистре. Но когда я пытаюсь получить имена столбцов после запроса с этим:

$query = Doctrine_Query::create()->select('m.*')->from("ProductsXsell m");
$collection = $query->execute();
$columns = $collection->getTable()->getColumnNames();
print_r($columns);

Вывод выглядит следующим образом:

Array
(
    [0] => id
    [1] => products_id
    ...
)

Я нигде не устанавливал атрибут case соединения с доктриной, поэтому он должен быть значением по умолчанию (Doctrine::CASE_NATURAL).

Это приводит к следующей ошибке:

Fatal error: Uncaught exception 'Doctrine_Record_UnknownPropertyException' with message 'Unknown record property / related component "id" on "ProductsXsell"' in /opt/hocatec/bin/libs/Doctrine/Doctrine/Record/Filter/Standard.php:55
Stack trace:
#0 /opt/hocatec/bin/libs/Doctrine/Doctrine/Record.php(1282): Doctrine_Record_Filter_Standard->filterGet(Object(ProductsXsell), 'id')
#1 /opt/hocatec/bin/libs/Doctrine/Doctrine/Record.php(1240): Doctrine_Record->_get('id', true)
#2 /opt/hocatec/bin/libs/Doctrine/Doctrine/Access.php(117): Doctrine_Record->get('id')
#3 /opt/hocatec/bin/models/HocaSync.php(368): Doctrine_Access->offsetGet('id')

person naitsirch    schedule 20.09.2012    source источник


Ответы (1)


Имя поля, которое вы хотите выбрать из своей базы данных, должно совпадать с тем, которое вы определили в своей модели. Чувствителен к регистру.

Подробнее об этом можно прочитать здесь. Первая часть рассказывает о столбцах и объясняет это.

Одна из проблем с совместимостью баз данных заключается в том, что многие базы данных различаются по своему поведению в отношении того, как возвращается набор результатов запроса. MySQL оставляет имена полей без изменений, что означает, что если вы выдаете запрос формы SELECT myField FROM..., то результирующий набор будет содержать поле myField.

К сожалению, именно так и поступают MySQL и некоторые другие базы данных. Например, Postgres возвращает все имена полей в нижнем регистре, а Oracle возвращает все имена полей в верхнем регистре. "Ну и что? Как это влияет на меня при использовании Doctrine?» — спросите вы. К счастью, вам вообще не нужно заморачиваться по этому поводу.

Doctrine прозрачно решает эту проблему. Это означает, что если вы определяете производный класс Record и определяете поле с именем myField, вы всегда будете обращаться к нему через $record-›myField (или $record['myField'], как вам больше нравится) независимо от того, используете ли вы MySQL или Postgres. или оракул и т.д.

Вкратце: вы можете называть свои поля как хотите, используя символы подчеркивания, camelCase или что-то другое.

ПРИМЕЧАНИЕ. В столбцах и псевдонимах столбцов Doctrine учитывается регистр. Поэтому, когда вы используете столбцы в своих запросах DQL, имена столбцов/полей должны соответствовать регистру в определении вашей модели.

person Guido    schedule 18.01.2013
comment
Одинокая ссылка считается плохим ответом, поскольку она сама по себе бессмысленна, а целевой ресурс не гарантируется в будущем. Было бы предпочтительнее включить сюда основные части ответа и предоставить ссылку для справки (как я делаю при редактировании ваш ответ). - person j0k; 19.01.2013
comment
Большое спасибо! Извините моя ошибка! но я думаю, что я написал главное, что имя модели должно быть одинаковым в его выбранном предложении. Затем я помещаю ссылку для получения дополнительной информации - person Guido; 21.01.2013
comment
Спасибо за ваш ответ, но он не поможет мне в моей проблеме. Я определил столбец ID в модели, но $collection->getTable()->getColumnNames() возвращает столбец в нижнем регистре. Почему это происходит? - person naitsirch; 22.01.2013
comment
Это происходит потому, что эта функция вызывает функцию getColumnName() для каждого поля вашей таблицы, и эта функция возвращает следующее: strtolower($fieldname); Вы можете видеть это в файле с именем Doctrine_Table. - person Guido; 22.01.2013