Просто простой пример: если я хочу создать таблицу с автозаполнением в 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 ... .. .
Из тонкого руководства :
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"
.
Сегодня я столкнулся с этой проблемой, и я обнаружил, что:
IDENTITY работает хорошо, потому что для PostgreSQL используется тип SERIAL, который автоматически создает связанную последовательность и устанавливает значение по умолчанию как nextval (sequence)
AUTO создает таблицу, а затем связанную последовательность, но не устанавливает значение по умолчанию для столбца id. Его можно установить, добавив следующий код:
/** * Webpage's ID * * @ORM\Id * @ORM\Column(type="integer", options={"default"="nextval('webpages_id_seq'::regclass)"}) * @ORM\GeneratedValue(strategy="IDENTITY") */ protected $id;
но, к сожалению, Doctrine сначала создает таблицу, поэтому нам нужно поменять таблицу и последовательность создания кода SQL, чтобы первая последовательность была создана
SEQUENCE работает так же, как AUTO