In Symfony with the Doctrine ORM how do you default autoincrement columns to integer and not bigint? - doctrine

It seems that in Symfony 1.4 with Doctrine that when generating auto-increment columns (id) it defaults to bigint. This seems like total overkill and I would just like to default it to an integer instead.
The following produces a primary key column named id that is a bigint
JobeetCategory:
actAs: { Timestampable: ~ }
columns:
name: { type: string(255), notnull: true, unique: true }
Is there a configuration file I can change this in. I don't want to have to manually add the id column as an integer.

Not that I'm aware of, no.
If you do end up manually adding the id columns into your schema you can specify their type as integer(4) to create a MySQL int field: http://www.symfony-project.org/doctrine/1_2/en/04-Schema-Files#chapter_04_data_types.

Related

Add column to table with Liquibase

I'm new to back-end development and currently trying to add a column to my app_user table. like below.
- changeSet:
id: 300520202335
author: Malindu De Alwis
changes:
- addColumn:
tableName: app_user
columns:
-column:
name: address
type: VARCHAR(255)
It gives this error
Caused by: org.yaml.snakeyaml.scanner.ScannerException: mapping values are not allowed here
in 'reader', line 23, column 22:
columns:
^
I use Spring boot and postgre sql. Please try to figureout the issue
I had the same issue, and I found there were 2 things wrong with the example code given on liquibase.com:
"columns" should be at the same indent as "tableName"
The whitespace between "-" and "column" mentioned by others
The example should be
changeSet:
id: addColumn-example
author: liquibase-docs
changes:
- addColumn:
tableName: person
columns:
- column:
name: middlename
type: varchar(50)
Somewhat disappointing that the official examples don't compile.
If you look at an example yaml test changelog like the one included here : https://github.com/liquibase/liquibase/blob/master/liquibase-core/src/test/resources/liquibase/parser/core/yaml/testCasesChangeLog.yaml -- you will be able to replicate an addColumn change type in yaml format that works. For example:
- changeSet:
id: using after column attribute
author: cmouttet
changes:
- addColumn:
columns:
- column:
afterColumn: firstname
name: middlename
type: varchar(50)
tableName: person
I believe #tobhai is correct though -- there is missing whitespace in - column.
I think the error results from missing whitespace between -column. Have you tried it with - column?

Doctrine2 + CodeIgniter and database table creation issue

I'm using Doctrine2 with codeIgniter, I've created some models in yml format. Using command line I've created the Proxies and Entities. When I'm trying to create the database tables, I'm getting the following error:
[Doctrine\ORM\Mapping\MappingException]
Invalid mapping file 'Entities.category.dcm.yml' for class
'Entities\category'.
Here's Entities.category.dcm.yml:
Entities\Category:
type: entity
table: categories
fields:
id:
type: integer
id: true
generator:
strategy: AUTO
name:
type: string
length: 50
nullable: false
description:
type: string
length: 255
First of all, check the paths configured for your entities and for the YML mapping driver.
Also, your Entities.category.dcm.yml contains mappings for Entities\Category, and not Entities\category.
As you can see in the base FileDriver Doctrine ORM does direct matching for mapped classes, and applies no normalization on the class names. Category and category are therefore different.

YAML syntax for unique columns in Propel

As far as I know to make a column unique the structure below should be used:
database:
table_name:
column_name: { ..., index: unique }
I want to make multiple columns unique at once. How am I going to do this?
Thanks in advance.
AFAIK you cannot do that. Oh, and you should use the XML format instead of the YAML one.
EDIT: actually, there is a possibility to handle that in YAML:
Article:
indexes:
my_index: [title(10), user_id]
See this fixtures file from the plugin for more information.
If you're talking about a composite unique key (e.g., having a unique key based on the combination of multiple fields in the same table), here's how you'd do that :
<unique name="document-version-index">
<unique-column name="document_id" />
<unique-column name="version_id" />
</unique>
As for the yaml syntax, I know you can do it in doctrine (see below), but not sure exactly of the propel format.
Doctrine format (--> from stackoverflow thread: primary key + composite primary key causing problem ) :
Pet:
columns:
pet_name: {type: string(32)}
owner_id: {type: integer}
indexes:
owner_name:
fields: [pet_name, owner_id]
type: unique

How to define current timestamp in yaml with doctrine?

I tried the following yaml code:
columns:
created_time:
type: timestamp
notnull: true
default: default CURRENT_TIMESTAMP
In the outputted sql statement, the field is treated as datetime instead of timestamp, which I cannot define the current timestamp in it...
If I insist to use timestamp to store current time, how to do so in yaml?
If you are willing to sacrifice some portability (see description of columnDefinition attribute) for the ability to use MySQL's automatic initialization TIMESTAMP (see MySQL timestamp initialization), then you can use the following:
Yaml:
created_time:
type: datetime
columnDefinition: TIMESTAMP DEFAULT CURRENT_TIMESTAMP
Annotation:
#ORM\Column(type="datetime", columnDefinition="TIMESTAMP DEFAULT CURRENT_TIMESTAMP")
Notice that DEFAULT CURRENT_TIMESTAMP does not work the same as Timestampable, and thus you cannot blindly exchange one for the other.
First and foremost, the former uses the date/time of the DB server, while the latter uses a Doctrine magic that calls PHP's date() function on your webserver. In other words, they are two distinct ways of getting the date/time, from two entirely different clock sources. You may be on big trouble if you use Timestampable, your web server runs on a different machine than your DB server, and you don't keep your clocks in sync using e.g. NTP.
Also, the DEFAULT CURRENT_TIMESTAMP being on the table definition makes for a much more consistent database model IMHO, as no matter how you insert the data (for instance, running INSERTs on the DB engine command line), you'll always get the current date/time on the column.
BTW, I'm also looking for an answer to the CURRENT_TIMESTAMP problem mentioned in the initial question, as this is (due to the reasons outlined above) my preferred way of keeping "timestamp" columns.
You could use the 'Timestampable' functionality in doctrine, eg:
actAs:
Timestampable:
created:
name: created_time
updated:
disabled: true
columns:
created_time:
type: timestamp
notnull: true
/**
* #var int
* #ORM\Column(type="datetime", columnDefinition="TIMESTAMP DEFAULT CURRENT_TIMESTAMP")
*/
protected $created;
after run ./vendor/bin/doctrine-module orm:schema-tool:update --force
Updating database schema... Database schema updated successfully! "1"
queries were executed
and run ./vendor/bin/doctrine-module orm:validate-schema
[Mapping] OK - The mapping files are correct. [Database] FAIL - The
database schema is not in sync with the current mapping file.
But FAIL for sync appear
Sorry for necroposting.
But i have encoutered the same problem. There is solution for doctrine 2 and postgreSql. I have used Gemdo extension and added following strings:
$evm = new \Doctrine\Common\EventManager();
$timestampableListener = new \Gedmo\Timestampable\TimestampableListener;
$timestampableListener->setAnnotationReader($cachedAnnotationReader);
$evm->addEventSubscriber($timestampableListener);
YAML:
created:
type: date
options:
default: 0
nullable: true
gedmo:
timestampable:
on: create
updated:
type: datetime
options:
default: 0
nullable: true
gedmo:
timestampable:
on: update
dump-sql:
ALTER TABLE users ADD created DATE DEFAULT CURRENT_DATE NOT NULL;
ALTER TABLE users ADD updated TIMESTAMP(0) WITHOUT TIME ZONE DEFAULT CURRENT_TIMESTAMP NOT NULL;
I suggest not to use "default" for timestamp at all.
It will bring unpredictable state in yaml in your application.
This video (PHP UK Conference 2016 - Marco Pivetta - Doctrine ORM Good Practices and Tricks) provides some more information about this topic.
I suggest you to to go through it and create a named constructor.
public function createTimestamp(string $priority, int $priorityNormalized)
{
$this->priority = $priority;
$this->priorityNormalized = $priorityNormalized;
}
I suggest to be stateless, good luck!
You can use:
default: '<?php echo date('Y-m-d H:i:s') ?>'

Doctrine YAML Data Fixture Question

where can i learn more abt creating database markup in yaml and data fixtures.
i followed a tutorial and they create a relationship like so: under relations in both User and Car. my qn is why is 'type: many' in Car. can i have it in User instead (just curious)?
abt data types. different database have different database support. i thought that in MySQL (InnoDB as used here) integer shld be tinyint(x), bigint(x), int(x) ... or string shld be varchar not string? isit not strict what i shld use here?
options:
type: INNODB
collate: utf8_general_ci
charset: utf8
User:
columns:
id:
type: integer
primary: true
autoincrement: true
name: string(300)
email: string(300)
phone: string(9)
car_id: integer
relations:
Car:
local: car_id
foreign: id
Car:
columns:
id:
type: integer
primary: true
autoincrement: true
brand: string(300)
relations:
Users:
class: User
foreign: car_id
local: id
type: many
UPDATE 1
"it is only necessary to specify the relationship on the end where the foreign key exists" in my example, that will be? do they mean the FK table (car) or the FK column (user)?
i dont see TEXT data type, is that clob (Character Large OBject)? – iceangel89 0 secs ago [delete this comment]
what is foreignAlias? is there a alias too?
UPDATE 2
this will be abit long, i just wish to clarify some of the code examples in the Doctrine YAML Schema Files docs page. focus on the relationships section -> in // comments
User:
columns:
username:
type: string(255)
password:
type: string(255)
contact_id:
type: integer
relations:
Contact:
class: Contact // if the table is named Contact, class will be Contact also?
local: contact_id
foreign: id
foreignAlias: User // whats alias for?
foreignType: one // one contact ... to ...
type: one // one user?
Contact:
columns:
first_name:
type: string(255)
last_name:
type: string(255)
phone:
type: string(255)
email:
type: string(255)
address:
type: string(255)
relations:
User:
class: User
local: id
foreign: contact_id
foreignAlias: Contact
foreignType: one
type: one
regarding the many to many example, what does the following mean?
attributes:
export: all
validate: true
tableName: group_table
refClass: GroupUser
where can i learn more abt creating database markup in yaml and data fixtures.
Doctrine manual, “YAML schema files” and “Data Fixtures” chapters.
can i have it in User instead (just curious)?
Yes, but this section will be called foreignType then. Here, an example:
User:
columns:
id:
type: integer
primary: true
autoincrement: true
name: string(300)
email: string(300)
phone: string(9)
car_id: integer
relations:
Car:
local: car_id
foreign: id
foreignType: many
abt data types...
Well, Doctrine column types and database column types are “slightly” different. Just compare list of Doctrine column types and, say, MySQL's one.
I know this is old, but these are things I've found confusing, and still do. In fact I'm not expert in all the possibilities, this is just based on what works for me. I think you may be looking for many-to-many relations, but I completely avoid the Doctrine support for them, and instead define my own association tables explicitly, so I only ever use one-to-many and one-to-one relations.
As noted in UPDATE1, you only specify the relationship on the end that has the foreign key.
In this case, User has a column car_id that is a foreign key that
refers to the id column of Car. So on the User end, the relation
is with Car, the local column containing the key value is
car_id, and the column in the other (foreign) table to which it refers is id.
Doctrine defines its own data types, and automatically maps them
onto the data types of the particular database you are using.
develop7 gave links to the documentation, or you can look in the
doctrine sources.
foreignAlias gives a name to the relation on the foreign side.
There is no alias because the name of the relation on the side
containing the foreign key is given by the name used at the level
below relations:, which is commonly specified as the name of the
table to which the foreign key refers.
Regarding UPDATE 2:
class: Contact The yaml for User says that it has a relation named Contact which refers to the class Contact. By default, class names and table names are the same; the yaml schema deals only with class names, though it is possible to tell it to use a different table name for a given class.
foreignAlias: User The name of the relation from Contact to User is "User". As explained above, there is nothing called "alias", the name of the relation from User to Contact is "Contact", because that's the name in the list of relations for User under which this line appears. Of course these default relation namings fall apart if you happen to have more than one relationship between the same two classes; you need the ability to give explicit relation names that differ from the class names. The names of relations are important because you use them in DQL joins.
foreignType: one A Contact (the foreign side) has one User
type: one A User (the local side) has one Contact.
Note that this example is a little unusual in showing explicitly both sides of the same relation. Normally, you'd show it only on the side containing the foreign key (the User side). Since a User contains a foreign key pointing to a Contact, the "type" can only be "one". But the foreignType could be "many", indicating that a given Contact could be pointed-to by many Users, though in this case it is specified that only one User can refer to a given Contact.
I don't actually know what would happen if you specified the type as "many". Implementing that would require an extra association table like many-to-many relations do, and I don't happen to know if Doctrine would create such a table "automatically" as it does for many-to-many relations. For my use of Doctrine, I avoid implicit machinery based on naming conventions that I don't understand as much as possible, so I turn off "detect_relations" and avoid many-to-many relations.

Resources