Is there a way of creating a table with a varchar as primary key (in Symfony/Doctrine)?
CREATE TABLE `table_name` (
`field_one` varchar(10) NOT NULL,
`field_two` decimal(10,2) DEFAULT NULL,
PRIMARY KEY (`field_one`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
When I try to create that using php bin/console make:entity it creates an integer id field as primary key.
Also is there a way of making a custom name for integer primary key field?
Doctrine's annotations works on primary key as well.
Here is an an example:
* #ORM\Column(name="field", type="string", length=30, nullable=false)
* #ORM\Id
private $field;
You you want to set your id yourself you have to disable generated value strategy:
#ORM\GeneratedValue(strategy="NONE")
Related
I've created a MySQL Model with a few tables, some of them with fk's to another table. I usually export the SQL from MySQL Model to my database using the "Forward Engineer SQL CREATE Script" inside File -> Export -> Forward Engineer SQL CREATE Script. The problem here is that when I generate the creation script, all my fk's become unique. I didn't check UQ option in MySQL Model but it creates a script with unique fk's anyway, so, I need to change the SQL file generated and remove all the unwanted uniques. Anyone has a clue why this is happening?
Generated script:
CREATE TABLE IF NOT EXISTS `u514786799_detranleiloes`.`Lotes` (
`createdAt` DATE NOT NULL,
`updatedAt` DATE NOT NULL,
`id` INT UNIQUE NOT NULL AUTO_INCREMENT,
`LeiloesId` INT UNIQUE NOT NULL,
`conservado` TINYINT NULL,
`numero` INT NOT NULL,
`CRDsId` INT UNIQUE NULL,
PRIMARY KEY (`id`),
INDEX `fk_Lotes_Leiloes_idx` (`LeiloesId` ASC),
INDEX `fk_Lotes_CRDs1_idx` (`CRDsId` ASC),
CONSTRAINT `fk_Lotes_Leiloes`
FOREIGN KEY (`LeiloesId`)
REFERENCES `u514786799_detranleiloes`.`Leiloes` (`id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `fk_Lotes_CRDs1`
FOREIGN KEY (`CRDsId`)
REFERENCES `u514786799_detranleiloes`.`CRDs` (`id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB
AUTO_INCREMENT = 1;
Running on mysql 5.7 + Doctrine 2.7/DBAL 2.9, with:
/**
* #ORM\Entity()
*/
class Entity {
/**
* #ORM\Id()
* #ORM\GeneratedValue()
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="string", length=100000, nullable=true)
*/
private $bigText;
}
orm:schema-tool:create creates the table Entity:
CREATE TABLE `Entity` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`bigText` mediumtext COLLATE utf8_unicode_ci,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
However, the schema-tool considers the table in need of update, running orm:schema-tool:update --dump-sql gives:
ALTER TABLE Entity CHANGE bigText bigText MEDIUMTEXT DEFAULT NULL;
Executing the update works fine, but doesn't help: it will still think the table needs updating.
I've tracked the issue to Doctrine\DBAL\Schema\Comparator's diffColumn method where the PlatformOptions of the current and the to-be column definition are compared. The to-be column has no PlatformOptions (which makes sense, as it's not on the platform yet, I suppose), while the current column does have them, namely charset and collation, in my test case here the defaults: ['charset' => 'utf8', 'collation' => 'utf8_unicode_ci'], which are set on the Column object by Doctrine\DBAL\Schema\MySqlSchemaManager->_getPortableTableColumnDefinition().
Poking around a bit in the source, I've found I can use EventListeners: because Doctrine\DBAL\Schema\AbstractSchemaManager->_getPortableTableColumnList() will emit an onSchemaColumnDefinition event and if I set $event->preventDefault() in there and create my own Column object and use $event->setColumn($column), I can circumvent MySqlSchemaManager->_getPortableTableColumnDefinition(). Or, I can go and fiddle with the other side and change the Schema created from the Classes / annotations and use postGenerateSchemaTable (which is much easier and feels less weird than messing with onSchemaColumnDefinition).
While I've learned a tiny bit more about internal flows, this feels way too complicated to handle mediumtext in MySQL without creating unnecessary ALTER TABLEs all the time.
Of course, I can sidestep the issue entirely by using type="text" instead of type="string" + a fixed length (which I've realized while browing issues here before asking this), but out of curiosity: am I missing something fundamental for dealing with fixed length fields in MySQL that fall into mediumtext length?
I'm working on a Symfony 3.4 project and I want for some columns of a table to use charset utf8mb4. The aim behind this is to allow emojis.
Here is an abstract of my Doctrine entity:
/**
* #ORM\Table(name="categories")
*/
class Category {
// ...
/**
* #var string
* #ORM\Column(name="description", type="string", length=255)
*/
private $description;
}
I first updated doctrine configuration:
doctrine:
charset: utf8mb4
Then, I updated the Doctrine configuration of the field category.description:
- * #ORM\Column(name="description", type="string", length=255)
+ * #ORM\Column(name="description", type="string", length=191, options={"charset"="utf8mb4"})
Note that I changed the length from 255 to 191 as utf8mb4 uses 4 bytes instead of 3 for utf8.
Finally, I ran update command:
bin/console doctrine:schema:update --dump-sql
What returned:
ALTER TABLE categories CHANGE description description VARCHAR(191) NOT NULL;
As you can see, there is no update about charset. Moreover, we can see a double whitespace between keywords VARCHAR(191) and NOT, letting suppose there should be something here.
The query I expect would be like this:
ALTER TABLE categories MODIFY `description` VARCHAR(191) COLLATE utf8mb4_unicode_ci NOT NULL;
I then ran the update command:
bin/console doctrine:schema:update --force
But when I re-run the --dump-sql command it returns the same query (with the double whitespaces) over and over.
Even when I manually set the charset of the column to utf8mb4 the query is still the same.
I use v2.6.3 of doctrine/orm.
Did I miss something in my configuration?
Does Doctrine handle column charset?
This does not answer my question as it's about changing collation of all tables. In my case I want to change collation of a single column of a specific table.
Short answer
Doctrine won't do this for you.
Alternative solution
Using DoctrineMigrationBundle allows to create migrations in plain SQL. Thus, you can edit auto-generated migrations to add charset/collation on desired columns.
Generate a new blank migration:
bin/console doctrine:migrations:generate
Then, add the ALTER statement:
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
final class Version20200113131732 extends AbstractMigration {
public function up(Schema $schema) : void {
$this->addSql('ALTER TABLE categories MODIFY `description` VARCHAR(191) COLLATE utf8mb4_unicode_ci NOT NULL;');
}
public function down(Schema $schema) : void {
$this->addSql('ALTER TABLE categories MODIFY `description` VARCHAR(255) COLLATE utf8_unicode_ci NOT NULL;');
}
}
Finally, just run the migration:
bin/console doctrine:migrations:migrate
It looks like doctrine partialy supports the change of collation on columns (only supported by Drizzle, Mysql, PostgreSQL>=9.1, Sqlite and SQLServer).
See doctrine annotations reference
/**
* #ORM\Table(name="categories")
*/
class Category {
// ...
/**
* #var string
* #ORM\Column(name="description", type="string", length=255, options={"collation"="ascii_general_ci"})
*/
private $description;
}
I have a table named Products in which there is a column id. It has foreign key relationship with prtyID column in ProductTypes Table. I just want to change the column id of Products table to prtyID. How is it possible? Is there any doctrine command is available for that? Please help me to fix this..
I'm not sure what you are trying to do here... id should be the primary id of Products, not a foreign key for another table. Please add your code if you ask a question.
Usually, Doctrine will use the property name to create the table column. So changing the property name to $prtyId would change your table column as well.
You can give every column the attribute "name" in the annotation of your entity, which will change the column name in your database:
/**
* #ORM\Column(type="integer", name="prtyID")
**/
protected $id;
Or, because you don't define the foreign keys yourself in Doctrine but the association, you can define the association like this:
/**
* #ORM\ManyToOne(targetEntity="ProductTypes")
* #ORM\JoinColumn(name="prtyID", referencedColumnName="id")
*/
protected $type;
This will create the column "prtyID" in your products table which is defined as the foreign key to productTypes primary colum "id"
I am trying to make a page where i handle my invoces. I have the invoice data in one tables and the invoice rows in another table. The tables looks as follows:
CREATE TABLE IF NOT EXISTS `Invoices` (
`I_Id` int(10) NOT NULL AUTO_INCREMENT,
`I_Number` int(4) NOT NULL,
`I_ClientId` int(10) NOT NULL,
`I_ExtraText` text NOT NULL,
PRIMARY KEY (`I_Id`)
) ENGINE=InnoDB
CREATE TABLE IF NOT EXISTS `InvoiceRows` (
`IR_Id` int(10) NOT NULL AUTO_INCREMENT,
`IR_InvoiceId` int(10) NOT NULL,
`IR_Price` int(10) NOT NULL,
`IR_Vat` smallint(2) unsigned NOT NULL,
`IR_Quantity` int(10) NOT NULL,
`IR_Text` varchar(255) NOT NULL,
PRIMARY KEY (`IR_Id`),
KEY `IR_InvoiceId` (`IR_InvoiceId`)
) ENGINE=InnoDB
Here is my mapping:
class Invoice {
/**
* #ORM\OneToMany(targetEntity="Row", mappedBy="invoice" ,cascade={"persist"})
*/
protected $rows;
}
class Row {
/**
* #ORM\ManyToOne(targetEntity="Invoice", inversedBy="rows", cascade={"persist"})
* #ORM\JoinColumn(name="IR_InvoiceId", referencedColumnName="I_Id")
**/
private $invoice;
}
I have been trying to follow the example at the doctrine docs on how to setup a One-To-Many, Bidirectional mapping. This is then connect with Zend Framework 2 and form collections. Pulling data works very good. I get all the rows of each invoice.
My Problem is when i want to write back to the database and save my changes. When i try to save i get the following error:
An exception occurred while executing 'INSERT INTO
MVIT_ADM__InvoiceRows (IR_InvoiceId, IR_Price, IR_Vat, IR_Quantity,
IR_Text) VALUES (?, ?, ?, ?, ?)' with params
{"1":null,"2":320,"3":0,"4":1,"5":"Learning your dog to sit"}:
SQLSTATE[23000]: Integrity constraint violation: 1048 Column
'IR_InvoiceId' cannot be null
What have i done wrong? When checking the data from the post value is not empty.
Edit: Full source can be found at Github
It seems IR_InvoiceId null, it expect the Id of Invoices (I_Id) value, so make sure while you are inserting the data in InvoiceRows table then here pass the Invoices (I_Id) value as IR_InvoiceId as you mention table relation..
Best Of Luck!
Saran