Skip to content

Laravel 5.5/5.6 Changing Columns Not Working #22029

@tprj29

Description

@tprj29
  • Laravel Version: 5.4.x/5.5.x
  • PHP Version: 7.1
  • Database Driver & Version: Postgres

Description:

I have multiple Laravel Schemas on which i want to migrate some migrations. One of my migrations is as following:

    <?php
    
    use Illuminate\Support\Facades\Schema;
    use Illuminate\Database\Schema\Blueprint;
    use Illuminate\Database\Migrations\Migration;
    
    class EditColumnPaymentMethodLengthOnRecurringPaymentsTable extends Migration
    {
        /**
         * Run the migrations.
         *
         * @return void
         */
        public function up()
        {
            Schema::table('recurring_payments', function (Blueprint $table) {
                $table->string('payment_method', 150)->nullable()->change();
                $table->text('test')->nullable();
            });
        }
    
        /**
         * Reverse the migrations.
         *
         * @return void
         */
        public function down()
        {
            Schema::table('recurring_payments', function (Blueprint $table) {
                $table->string('payment_method', 18)->nullable()->change();
                $table->dropColumn('test');
            });
        }
    }

What happens is that the new column is added to the database (and dropped if rolledBack) but the column 'payment_method' always has the length of 18 characters. Except for the first Schema this one works fine.

This is the command i migrate with:

    <?php
    
    namespace App\Console\Commands;
    
    use App\Account;
    use App\Support\Schema;
    use Illuminate\Console\Command;
    
    class MigrateTenantsCommand extends Command
    {
        /**
         * The name and signature of the console command.
         *
         * @var string
         */
        protected $signature = 'tenant:migrate {--force : Force the operation to run when in production.}
                    {--pretend : Dump the SQL queries that would be run.}
                    {--seed : Indicates if the seed task should be re-run.}
                    {--step : Force the migrations to be run so they can be rolled back individually.}';
    
        /**
         * The console command description.
         *
         * @var string
         */
        protected $description = 'Migrate all tenants';
    
        /**
         * Create a new command instance.
         *
         * @return void
         */
        public function __construct()
        {
            parent::__construct();
        }
    
        /**
         * Execute the console command.
         *
         * @return mixed
         */
        public function handle()
        {
            $tenants = Account::all();
            foreach($tenants as $tenant)
            {
                $schema = new Schema;
    
                // Migrate into the new schema
                $schema->migrate(
                    $tenant->schema,
                    $this->getOptionsFromArgs()
                );
            }
        }
    
        private function getOptionsFromArgs()
        {
            $options = [
                '--path' => 'database/migrations/tenants/schema'
            ];
    
            if($this->option('force'))
            {
                $options['--force'] = true;
            }
            if($this->option('pretend'))
            {
                $options['--pretend'] = true;
            }
            if($this->option('seed'))
            {
                $options['--seed'] = true;
            }
            if($this->option('step'))
            {
                $options['--step'] = true;
            }
            return $options;
        }
    }

someone pointed out to run the command with --pretend. When i did this i got an exception: [Doctrine\DBAL\Schema\SchemaException] There is no column with name 'payment_method' on table 'recurring_payments'.

It is not a problem with the table being there or not. It is probably a problem with Doctrine not finding the right Schema Config and therefor using the public Schema config. In the public schema the table is not present but i don't want to use the public schema. What i'm doing wrong here, how can I tell Doctrine to use the right Schema config? How is it that Doctrine is finding the right config the first time at least that is wat it looks like.

The Schema/Schema Class of Doctrine:

    public function __construct(
            array $tables = array(),
            array $sequences = array(),
            SchemaConfig $schemaConfig = null,
            array $namespaces = array()
        ) {
            if ($schemaConfig == null) {
                $schemaConfig = new SchemaConfig();
            }
            $this->_schemaConfig = $schemaConfig;

            $this->_setName($schemaConfig->getName() ?: 'public');
    
            foreach ($namespaces as $namespace) {
                $this->createNamespace($namespace);
            }
    
            foreach ($tables as $table) {
                $this->_addTable($table);
            }
    
            foreach ($sequences as $sequence) {
                $this->_addSequence($sequence);
            }
        }

Steps To Reproduce:

  1. add change() to one of your migrations
  2. switch between multiple schema's

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions