In the midst of developing a Laravel 4 app, I've decided to start making use of Laravel's Migration feature.
Question: Should we write migrations for creating all the tables that we currently have in the database? Or do we only write migrations for future changes?
There is no complete right answer to this. It all depends on a lot of variables, like your style of development, how many people you're working with and in what kind of environment (single production DB? multiple dev DBs?), what your requirements with migrations are, etc. etc.
If you do decide to write migrations for the entire DB up until this point, you'll need to make sure that your migrations can handle any potential conflicts. Making use of Schema::has() and such to verify tables exist prior to attempting to create them, and such.
Alternatively, you can write migrations as if the DB has a clean slate, and enforce any devs to start with an empty DB prior to running migrations. This has risks, so be careful. Make sure you have backups in case your migration forgot something and you need to modify it.
So, TL;DR: Is using migrations for your entire structure part way through a project necessarily a bad thing? No. Is it right for your application? That entirely depends.
Related
I'm about to start building an API for an existing app with the DB already in production. Functionality will slowly be ported to the API in the future and the app will become more "API-centric".
One of the main starting points is to adopt migrations and a build process. I have reservations on the best way to create migrations for an existing schema without breaking production when they are executed.
As we would like to move quickly with porting functionality over to the API, we ideally want to recreate our current schema as part of our build process and get some core unit tests in place - as opposed to just creating migrations for future changes.
This is where I become unsure as to the best place to start.
What is the best approach for a task like this?
Could the current schema be imported as our first migration?
Could this initial migration be wrapped in something like:
if ( App::environment() !== 'production' ) to ensure it isn't executed in a production environment?
Is it ok to exclude a migration for a particular environment or could this cause problems?
Is there maybe another approach or something stupidly simple I'm missing? :)
I created a tool not to long ago that will generate all the migrations for your current database schema. It also adds the newly created migrations to the migrations table, as the tables already exist. You can get it here: https://github.com/Xethron/migrations-generator
Secondly, I use the following line of code in my DatabaseSeeder, but you can add it to any function you wish to disable in production:
if (App::environment() === 'production') {
exit('Don\'t be stupid, this is a production server!!!');
}
It shouldn't be a problem if you stop execution by throwing an error or as I do above. If you don't, Laravel will believe the changes happened successfully and remove them from the migrations table, and cause errors when running your migrations. The only exception is if you exclude both the up and down code (But I can't see why you would want to do that)
Hope this helps.
I wouldn't suggest running migrations in production environment at all, but if you must then make a backup copy of the database first and also create a copy of the database locally and do the migration there then test to make sure it all works properly.
You could create your first migration and manually add all the schema layout to it. But I would actually do this in a few migrations to have each table as its own migration.
Since migrations are run from the CLI using artisan you can pass the environment and the database you want the migration to be run on:
artisan migrate --database="connectionName" --env="local"
There is no issue running migration on a particular environment besides what I stated above for production.
Remember to add all existing schema layouts from step 1 (the migration file name excluding the extension e.g. 2014_03_25_143340_AddCountriesTable) to the migrations table in the database, otherwise running the command in step 2 will throw errors about table already exist.
Hope this helps.
I asked this question on Reddit, but received no answer. I thought I would try here, instead.
I am new to Laravel, and have been going over the documentation and also watching Jeffrey Way's NetTuts videos. However I haven't gotten in too deep just yet, so if this is answered clearly somewhere else, please just point me in that direction.
I come from a CodeIgniter background, and for all projects I have done with it, I typically design my databases in MySQL Workbench. I also use this to make changes to the schema, and also as a visual map of the database. The MySQL Workbench file generally gets passed around with the other developers via Git.
Laravel seems to want you to create your tables using migrations, which seems a bit counter intuitive coming from the MySQL Workbench side. I understand that migrations act as a version control for the database, which seems pretty nice. However, other than that, I don't quite get the point just yet.
Can anyone explain to me why I should be building the tables out via the migrations feature of Laravel vs. the way I've been doing it?
Laravel is a PHP framework. Like other frameworks, such as Zend, your development to deployment timeframe will be significantly reduced, as well as developing within a framework that can be understood by other developers as your projects becomes larger and you need more developers involved in the future.
Migrations, as part of Laravel, are designed to quickly and easily setup a database scheme without the need to type any MySQL. It also presents the schema correctly. As your schema exists within a file, you can easily rollback and transport your schema with ease.
Well, this is a valid concern. While Laravel doesn't specifically force you to use it, I can think of a few reasons for its implementation:
Compatibility. It works with almost any database. If you ever decide to change from MySQL to PostgreSQL, there's very little to change.
Version control. As you mentioned yourself, it allows you to have control over what's changed in your database, and provides quick and easy way to update your already running database.
Easy of use. It's incredibly easy to call it through the command line. Meaning you won't have any problems creating your database on the server side, through a shell.
The main reason Laravel has migrations is because version control. When you create a migration the name has a date attached to it. I use Laravel myself and I absolutely love migrations. Teamed up with the Schema builder it makes my life so much easier not using ancient MySQL methods. Here's some examples of the Schema and migration
Simple Command To Create A New Migration File:
php artisan migrate:make create_users_table
Inside The Users Table Migration File:
Schema::create('users', function($table){
$table->increments('id'); [will create a increments field with name of ID]
$table->string('username'); [string field with name of username]
$table->string('password'); [password is a special field]
$table->text('body'); [string field with name of username]
});
At the bottom all you need to add is this:
Schema::drop('users');
Then you run the migrate command:
php artisan migrate
It will add all the columns to the table.
if you ever want to take back or add to the database all you need to do is run this
php artisan migrate:rollback
[you can add specific commands here to only rollback certain tables]
Is it safe to build a Yii application over a SQL Server database which is being used by another software?
The ideia is to migrate that desktop software for a WebApp but I must let the database structure untouched.
It's a quite complex database and I have very complex SQL Queries as well, so I should avoid DAO and AR. I've been looking for some information around the web but it's not clear to me how safe it will be this process. Should I build all the application with RAW SQL and be careful with it's implementation?
Can anyone of you show me the right path I should follow?
Thanks in advance
It is absolutely safe to do this, with Yii you can use any database structure you need. You'll only need to create your models based on your current database structure.
Here a quick guide to use Yii with SQLServer http://www.yiiframework.com/wiki/192/config-use-ms-sql-server-2005-2008/
You can use just plain SQL with Yii, have a look at http://www.yiiframework.com/doc/api/1.1/CDbCommand
But if you want more flexibility, I can recommend you the following way.
create an initial database migration, just execute() a plain SQL dump from your exisiting database.
create database migrations as you need them
apply migrations
develop
go to step 1. if you want to test with newer data and reapply migrations to your database
shut down old application
As your migrations are versioned with your application, you could eg. maintain a branch with the old db-schema and work parallel on an updated version with another db-schema.
I am building a complex application but i want to know that is it safe to use doctrine migrations in production.
For eg. the site has been used for 1 year and company wants to add extra attribute to user table.
So do i straight way chnage by going in database or through doctrine migrations
This is one of the intended uses (and benefits) of migrations - to automate the changes to your database quickly and accurately. Yes, they can and in most cases should be used to update your database in production.
Edit: The Symfony2 documentation also explains clearly this is one of the purposes of migrations.
Of course, the end goal of writing migrations is to be able to use them to reliably update your database structure when you deploy your application. By running the migrations locally (or on a beta server), you can ensure that the migrations work as you expect.
...
Yes it would be safe.
I would just add an extra attribute in the User entity. Then run the doctrine:generate:entities command. That should generate the get/set methods. Then just update your database using doctrine:schema:update --force. That should add it into your database table.
(Make this CW if needed)
We are two developers working on a web application based (PHP5, ZF, Doctrine, MySQL5). We are working each with a local webserver and a local database. The database schema is defined in a YAML file.
What's the best way to keep our database schemas in sync?
Here's how we do it: Whenever developer "A" makes a change, he generates a migration class. Then he commits the migration file developer "B" executes the migration class.
But creating a migration class on every db change is a rather tedious process.
Do you have a better solution?
I don't know how you do in the Zend Framework with Doctrine. Here's how I would do it in Symfony with Propel. Though the exact procedure may vary, but the underlying concept is the same.
I have unit tests on my DAL.
Whenever the schema changes, we check in the yml and the generated ORM code ( You do have a source control, don't you). I set the check-in to auto-mode, meaning I will get all the check-in instantly.
If the schema changes don't affect my thing, then I would just ignore the changes. But if the schema changes break my thing, then I will rebuild my form, ORM classes and whatnot by using symfony propel build command. Rebuilding those infrastructures is just a single command line thing, so there is no problem for me.
Finally, after rebuilding, I will run my unit tests, to make sure everything is OK. If not, I better get them fixed!
I see that this question is already answered but Doctrine can migrate your databases for you without having to blow away the whole thing. We use this for every schema change where one developer changes his/her local yaml file, generates new models locally, creates a migration using Doctrine, runs that migration locally to change the db, then checks in both the new yaml file and the migration. Then other developers check out the changed yaml file and migration, then they generate new models and run the migration to sync their db. Deploying the code to our QA and production environments is pretty much the same process.
More information on Doctrine migrations can be found on the Doctrine site.