How can I change table name without creating a new one?
I have a table with some records in it, if i change the table name in mapping file (xml) and run app/console doctrine:schema:update --force Doctrine leaves an old table and generates a new empty table.
Unfortunately Doctrine is not smart enough to detect such renaming because it would have a big performance impact. So instead of detecting such changes you have to rename the table manually during the update process.
To automate this process you can use Doctrine migrations for which you can find the documentation here:
Doctrine Migrations Bundle (Symfony2)
Related
I am working with Symfony and Doctrine. In the middle of the project I need to implement the Doctrine migrations, because the DB changes were too much and I need a better way to handle it.
How is the best way to start with the migrations, when there is already data on prod and it need to stay there and not to be touched?
My plan will be:
On my test system
drop all tables
run php bin/console doctrine:migrations:diff
The new automatic migration file, which I become holds all the table structures of my current state
go live to the table "migration_versions" and add the ID of this migration, so it will be skipped by the first run of the
migrations
run the migration php bin/console doctrine:migrations:migrate
In this way, I have all the structures from my entities, but I will not destroy my live data.
What do you thing?
If there is already some data on production, then your best take is to do a make:migration or doc:mig:diff from the current schema state. That will generate only the necessary sql that will update the new changes, but nothing else. Your first migration version will countain only the sql to update from the current state, and not from the beginning of times.
And also, once you have adopted this, you have to do every database modification under migrations. For example, if you need to add a non-nullable field, you usually add the new field with not null, then fill all the rows of that field with a default or calculated one, and then alter the table to make the field not nullable. Migrations will generate some boilerplate code to make your life easier, but it also requires a lot of care from the development team. Always test them first in a database that you can get rid of. And you will run into FK constraints and lots of other issues, but basically you have to solve them doing SQL.
Old thread here, but what I do in cases like this:
Backup dev database (structure and data, but with table create statements protected with checking so they are only created if they don’t already exist)
Drop all tables so the database is empty
Generate migration (since database is empty, the generated migration will constitute all commands necessary to generate your entire schema)
Run migration you just generated to build schema
Import test data from your dump
That puts you right back where you started but with an initial migration that can build your schema from nothing.
I am working with doctrine:migrations:diff in order to prepare database evolutions.
This command creates files into app/DoctrineMigrations
Thoses files contains sql commands in order to upgrade or downgrade database scructure.
I want to store those sql commands into the database itself. In fact, i have several instances of databases. If sql commands are store into files, it is a big problem.
I have read somewhere that DoctrineMigrations bundle can create a table called "migration_versions", but i do not manage to find where i have read this...
I cannot really understand what you're trying to do.
Migrations are used when your code needs altered database structure. For example, a new table or a new column. These new requirements for a table or column comes from your newly written code, so it's only natural to place the migrations also as a code in your repository.
How and when would migrations even get to your database? How would you guarantee that migration is executed before the code changes, which use that new structure?
Generally, migrations are used in this way:
You develop your code, add new features, change existing ones. Your code needs changes to database.
You generate doctrine migration class, which contains needed SQL statements for your current database to get to the needed state.
You alter the class adding any more required SQL statements. For example, UPDATE statements to migrate your data, not only the structure.
You execute migration locally.
You test your code with database changes. If you need more changes, you either add new migration, or execute migration down, delete it and regenerate it. Never change the migration class, as you'll loose what's supposed to be in the database and what's not.
You commit your migration together with code that uses it.
Then comes the deployment part:
- For each server, upload the code, clear and warm-up cache, run other installation scripts. Then run migrations. And only then switch to the new code.
This way your database is always in-sync with current code in the server that uses that database.
migration_versions database table is created automatically by doctrine migrations. It holds only the version numbers of migration classes - it's used for keeping track which migrations were already run and which was not.
This way when you run doctrine:migrations:migrate all not-yet-ran migrations are executed. This allows to migrate few commits at once, have several migrations in a commit etc.
I have just discovered the ORM\Index annotation and have gone through my entities to add in all the indexes I should have on my tables.
But I now don't know how to apply these changes to my database.
I tried doctrine:migrations:diff but it didn't pick up the changes.
Is there any other commands that I can use (without rebuilding the database) or will I have to apply all the indexes manually in mysql?
edit: I was being stupid. The indexes I added to test were on ManyToOne fields, which already get indexes. I've added an index to one of my data fields and migrate picked it up.
doctrine:schema:update --dump-sql
will give you a list of all the mysql changes that will occur.
doctrine:schema:update --force
will apply those updates for you (do not do this on production)
I have some beginners questions regarding Symfony 2 which I cannot get clear answers for from previous questions (perhaps because they are genuinely basic)
When you create a new symfony2 project from the command line and specific the database name and passwords, is this meant to automatically create the database (which you can see in phpmyadmin) or does one manually do this.
Following from this, if one creates a number of entities and then uses
doctrine:schema:update
Should the specified tables be automatically created in the database you have specified in the projects "parameters.yml" file.
I have performed "doctrine:schema:update --force" which then gave me
Updating database schema...
Database schema updated successfully! "2" queries were executed
But no tables were created. So I tried again, to see what the message would be...
unknown-ec:35:86:4d:41:5e:symfony simonalice$ php app/console doctrine:schema:update --force
Nothing to update - your database is already in sync with the current entity metadata.
unknown-ec:35:86:4d:41:5e:symfony simonalice$
So clearly Doctrine thinks its in synch - but no tables in phpmyadmin.
Clearly complete beginners stuff....but I would be grateful for some steerage on this from a Symfony 2 veteran.
To answer your questions:
No, creating a new Symfony project will not create your database (or the user connecting to it). You still need to do that and I would recommend you create a dedicated user for your application with suitable permissions. You'll need to use a database user with administrative privileges to do this. For security reasons, it's best to not use your database administrator account with your application. To instruct doctrine to create your database (once you have your db user and connection parameters set), you can run the php app/console doctrine:database:create console command.
Yes, running the doctrine:schema:update console command will generate your database entities, but it won't/can't create your database. You can also use the --force option to apply changes you've made since the last update. These updates will still be bound by any column constraints you've defined, so if for example you change an existing nullable column to not null, you'll get an error if records already exist with null values.
Hope that helps.
We're using Doctrine Migrations to keep the application DB in sync across versions. The app will be installed each time we get a new customer meaning a new DB for each installation.
Now, the new DB will have all DB changes in the migrations file in place but will try to execute the migration files as they are not registered in the migrations table.
What's the best way to handle this situation?
Just after fresh install to fill current schema use this commands:
Create new empty chema of current version
./bin/console doctrine:schema:create
Fill out the migration records with the current version (without actually run the migrations - schema already has current version after first command)
./bin/console doctrine:migrations:version --add --all
This command adds records of the migrations and doctrine:migrations:status will show you that there is no migrations need for the current verions.
Thats all!
As mentioned in my comment, I've successfully created a blank database schema just by using Doctrine migrations. I believe it's necessary to create the empty database first (php app/console doctrine:database:create) and then run the migrations task.
The only potential issue I can think of is that any base data that your app requires to function will either need to be in the migrations files or will need to be inserted separately.
As an aside, running the all the migrations in one go has picked up a couple of small errors that I'd missed when just executing one at a time.
I think you can pick the very first migration class, copy it and rename with just one second before.
So, if your first class is 2016060712284351 you should create a new class called 2016060712284350. This way it is executed just before the real migrations.
In this newly created class you setup your database creating all needed tables. This way, when you run migrations the first thing is done is to create the database with all the tables and then the real migrations are run.
Anyway I'm not sure this is the real way to proceed.
Migrations are needed to update the database schema, but if you are creating a new database for each user, each of the new users will have the new schema as per entities mapping. So a migration is not needed.
You need to run migration only for OLD USERS' DATABASES, am I right?