Make Doctrine пропускать поля / столбцы при вставке в которые доступны только для чтения

#sql #doctrine-orm #persistence #hydration

#sql #doctrine-orm #постоянство #гидратация

Вопрос:

У меня есть таблица PostgreSQL t со столбцами t1 , t2 , …. Мне нужно отфильтровать коллекцию объектов, прежде чем удалять все объекты по Doctrine из соображений эффективности. Однако Criteria класс Doctrine слишком ограничен, поскольку он должен работать на уровне объектов PHP (после гидратации) и на уровне SQL (после гидратации). Поэтому я решил создать представление SQL, которое по существу отражает таблицу T и добавляет дополнительный динамический столбец, который вычисляет выражение на уровне SQL. Следовательно, у меня есть

 CREATE VIEW v AS SELECT t.*, (t.t1 <> t.t2) AS flag FROM t AS t;
  

(Примечание: приведенное выше логическое выражение для flag на самом деле намного сложнее. Здесь он служит заполнителем.)

Объект Doctrine T связан с представлением вместо таблицы и имеет дополнительное поле $flag . Я использую ORMChangeTrackingPolicy( "NOTIFY" ) этот класс сущностей таким образом, что поле $flag никогда не помечается как грязное, а Doctrine никогда не включает его в UPDATE оператор. На уровне PHP поле $flag синхронизируется с полями, которые формируют логическое выражение, с помощью соответствующих методов получения / установки.

PosgreSQL поддерживает INSERT INTO , UPDATE и DELETE в представлениях, если поля представлений являются элементарными выражениями одной и той же таблицы.

Проблема: если новая сущность сохраняется в первый раз, Doctrine включает поле $flag в INSERT INTO инструкцию, даже если $flag оно помечено как не загрязненное. Это вызывает следующее исключение SQL: «ОШИБКА: не удается вставить в столбец «флаг» представления «v» ПОДРОБНЕЕ: столбцы представления, которые не являются столбцами их базового отношения, не подлежат обновлению».

Есть ли какой-либо способ указать Doctrine не включать этот столбец? Есть ли способ пометить столбец как доступный только для чтения?

Ответ №1:

Для тех, кто столкнулся бы с такой же проблемой, как я. Начиная с версии Doctrine >2.11 , @Column в аннотации добавлены новые полезные опции (ссылка на документы) :

  • updatable
  • insertable

Поля с этими параметрами, установленными на false , теперь игнорируются в сгенерированном SQL-запросе.