Подтвердить что ты не робот

Doctrine2 не устанавливает последовательность по умолчанию для столбца id (postgres)

Простой пример: если я хочу создать таблицу с автозаполнением в postgres, я запустил этот sql:

CREATE SEQUENCE person_id_seq  START 1;

CREATE TABLE person (
    id         integer PRIMARY KEY DEFAULT nextval('person_id_seq'),
    name       varchar(100) NOT NULL
);

и в доктрине я установил все свойство

class Person {

/**
 * @Id
 * @Column(type="integer", nullable=false)
 * @GeneratedValue(strategy="SEQUENCE")
 * @SequenceGenerator(sequenceName="person_id_seq", initialValue=1, allocationSize=100)
 */
private $id;

но когда я сгенерировал sql (доктрина php orm: schema-tool: create --dump-sql), я получил ее:

CREATE TABLE person (
    id INT NOT NULL,
    name VARCHAR(100) NOT NULL
);
CREATE SEQUENCE person_id_seq INCREMENT BY 100 MINVALUE 1 START 1

но не устанавливайте его по умолчанию

\ d человек

      Column       |              Type              | Modifiers
-------------------+--------------------------------+-----------
 id                | integer                        | not null
...
..
.
4b9b3361

Ответ 1

Из точное руководство:

4.8.1. Стратегии генерации идентификаторов
...
AUTO (по умолчанию): Сообщает Doctrine о выборе стратегии, которая предпочтительнее используемой платформы баз данных. Предпочтительными стратегиями являются IDENTITY для MySQL, SQLite и MsSQL и SEQUENCE для Oracle и PostgreSQL. Эта стратегия обеспечивает полную мобильность.
...
IDENTITY: указывает Doctrine на использование специальных столбцов идентификации в базе данных, которые генерируют значение при вставке строки. В настоящее время эта стратегия не обеспечивает полной переносимости и поддерживается следующими платформами: MySQL/SQLite (AUTO_INCREMENT), MSSQL (IDENTITY) и PostgreSQL (SERIAL).

Они предлагают AUTO для максимальной переносимости:

/**
 * @Id
 * @Column(type="integer", nullable=false)
 * @GeneratedValue
 */

Это должно создать и установить для вас последовательность. Альтернативой может быть запрос столбца serial с использованием стратегии IDENTITY:

/**
 * @Id
 * @Column(type="integer", nullable=false)
 * @GeneratedValue(strategy="IDENTITY")
 */

Этот должен создать ваш столбец id как тип serial, а PostgreSQL создаст последовательность и настроит для вас значение по умолчанию.

Документация указывает, что то, что вы делаете, должно работать, но документация обычно обеспечивает только упрощенную версию действительности.

Попробуйте использовать strategy="AUTO". Если это не сработает, попробуйте strategy="IDENTITY".

Ответ 2

Сегодня я столкнулся с этой проблемой, и я обнаружил, что:

  • ИДЕНТИФИКАЦИЯ работает хорошо, потому что для PostgreSQL используется тип SERIAL, который автоматически создает связанную последовательность и устанавливает значение по умолчанию как nextval (sequence)

  • AUTO создает таблицу, а затем связанную последовательность, но не устанавливает значение по умолчанию для столбца id. Его можно установить, добавив следующий код:

    /**
     * Webpage ID
     *
     * @ORM\Id
     * @ORM\Column(type="integer", options={"default"="nextval('webpages_id_seq'::regclass)"})
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    protected $id;
    

    но, к сожалению, Doctrine сначала создает таблицу, поэтому нам нужно поменять таблицу и последовательность создания кода SQL, чтобы первая последовательность была создана

  • SEQUENCE работает так же, как AUTO