Doctrine 2 + unsigned value

Is it possible to specify a column type of unsigned integer in Doctrine 2?

37356 次浏览

You can but you will loose portability. Use columnDefinition attribute and set it to integer unsigned. The actual code depends on what you are using.

columnDefinition: DDL SQL snippet that starts after the column name and specifies the complete (non-portable!) column definition. This attribute allows to make use of advanced RMDBS features. However you should make careful use of this feature and the consequences. SchemaTool will not detect changes on the column correctly anymore if you use “columnDefinition”.

Doctrine reference: https://www.doctrine-project.org/projects/doctrine-orm/en/latest/reference/annotations-reference.html#column

Decimals will allow for such large numbers and allow you to keep the SchemaTool, just set the scale to 0.

<?php
/**
* @Column(type="decimal", precision=20, scale=0, nullable=false, unique=true)
*/
Protected $facebookId;

Checkout a full writeup on why here. [EDIT](link does not work) I have pasted the article below. It was written by me anyways ;)

unsigned numbers so large your brain will explode! w/Doctrine 2

ORMs have an inherent problem. How do you take a datatype only some RDBMSs support and allow you to use it anyways. Well when it comes to Doctrine 2 and unsigned numbers they got a little lazy.

All I want to do is store my 64bit facebook IDs. How hard is that? Well my RDBMS is mySQL so all I really need is an unsigned bigint.

<?php
/**
* @Column(type="bigint", nullable=false, unique=true, columnDefinition="unsigned")
*/
Protected $facebookId;

This seems find and dandy until you read this:

columnDefinition: DDL SQL snippet that starts after the column name and specifies the complete (non-portable!) column definition. This attribute allows to make use of advanced RMDBS features. However you should make careful use of this feature and the consequences. SchemaTool will not detect changes on the column correctly anymore if you use “columnDefinition”. Basically this feature let’s you free form unsupported things into the column definition. Making unsigned numbers technically UN-SUPPORTED! Not to mention my dev and QA deployment systems rely heavily on the SchemaTool. We can thank a combination of lazy developers at Doctrine and sqlite3 for this little nugget of crazy town.

This immediately prompted a google search. I don’t like thinking if I don’t have to. What did I find? Everybody’s using varchars. VARCHARS!?!? I about had a heart attack. That was just unacceptable.

Thus enters decimal. It’s perfect. The storage size is variable and it’s stored in binary so indexing is super fast. We just set the decimal precision to zero and voilà. The ORM can port this to any RDBMS, it’s big enough for us not to care about the unsupported signed/unsigned issue and it’s lightning fast. decimal(20,0) should handle our facebook size of eighteen quintillion four hundred and forty six quadrillion seven hundred and forty four trillion seventy three billion seven hundred and nine million five hundred and fifty one thousand six hundred and fifteen quite nicely.

<?php
/**
* @Column(type="decimal", precision=20, scale=0, nullable=false, unique=true)
*/
Protected $facebookId;
/**
* @ORM\Column(name="id", type="integer", options={"unsigned"=true})
*/

There is no place in the doc (that I've seen) that speak about this, but it works.

Update

Definition in Yaml (as of 2.4 for primary key)

id:
type: integer
options:
unsigned: true

Doctrine 1 documentation and Doctrine 2 documentation said you can do it by this ways:

PHP annotations:

/**
* @Column(type="integer", name="some_field", options={"unsigned":true})
*/
protected $someField;

Yaml: (see docs)

MyEntity:
fields:
someField:
type: integer
column: some_field
options:
unsigned: true

Hope this helps to someone to save a time ;)

I have the same problem with doctrine 2. and i solve it the same way, but there are some advantages :

/**
* @ORM\Column(name="id", type="integer", options={"unsigned"=true})
*/

Running diff migration bin/console doctrine:migration:diff will do some magic.In fact, if the column was a foreign key in other tables, the doctrine is able to find them out and apply the same update row as the concerned column.

You just need in your migration to remove foreign keys before and add them after the column type transformation.

Using attributes (PHP >= 8, Doctrine >= 2.9):

use Doctrine\ORM\Mapping as ORM;


/// ...


#[ORM\Column(type: 'integer', options: [
"unsigned" => true
])]

Source: https://www.doctrine-project.org/projects/doctrine-orm/en/2.11/reference/attributes-reference.html#column