迁移到FOSUserBundle

时间:2013-06-30 18:17:29

标签: php symfony fosuserbundle

到目前为止,我们一直在使用Symfony2中的自定义身份验证系统。我们现在正在扩展我们的功能,它已进入FOSUserBundle节省时间的阶段。

我已经使用Composer安装了FOSUserBundle并将其添加到appKernel.php。

关于实体,由于已经有一个User实体,我刚刚删除了FOS包中的AbstractUser实体已经拥有的字段并对其进行了扩展:

use FOS\UserBundle\Entity\User as BaseUser;
...
class User extends BaseUser

我将使用doctrine更新架构:schema:update --force并获取以下内容:

  [Doctrine\DBAL\Schema\SchemaException]                 
  The table with name 'lifemirror.user' already exists. 

嗯,是的,用户表已经存在,但该命令应该更新它。我更改了用户实体中的表名并执行了--dump-sql以查看发生了什么,它似乎保留了表但删除了结构:

ALTER TABLE user DROP email, DROP username, DROP password, DROP invitation_code, DROP picture_file;

所以我认为User实体可能正在其他地方使用,但我不知道在哪里。

根据Pazi的建议,我安装了doctrine migrations bundle并试图创建一个mgiry。它生成以下

/**
 * Auto-generated Migration: Please modify to your need!
 */
class Version20130701134939 extends AbstractMigration
{
    public function up(Schema $schema)
    {
        // this up() migration is autogenerated, please modify it to your needs
        $this->abortIf($this->connection->getDatabasePlatform()->getName() != "mysql");

        $this->addSql("CREATE TABLE film_today (id INT AUTO_INCREMENT NOT NULL, title VARCHAR(255) DEFAULT NULL, description LONGTEXT DEFAULT NULL, id_user INT DEFAULT NULL, suggest_date DATE DEFAULT NULL, PRIMARY KEY(id)) DEFAULT CHA$
        $this->addSql("CREATE TABLE user1 (id INT AUTO_INCREMENT NOT NULL, firstname VARCHAR(255) DEFAULT NULL, lastname VARCHAR(255) DEFAULT NULL, country VARCHAR(255) DEFAULT NULL, birthdate DATE DEFAULT NULL, PRIMARY KEY(id)) DEFAU$
        $this->addSql("DROP TABLE cinema");
        $this->addSql("DROP INDEX id_user ON session");
        $this->addSql("ALTER TABLE job CHANGE id id INT AUTO_INCREMENT NOT NULL, CHANGE cinema cinema INT NOT NULL, CHANGE name name LONGTEXT NOT NULL, CHANGE status status VARCHAR(10) NOT NULL");
        $this->addSql("ALTER TABLE film_location CHANGE screening_description screening_description VARCHAR(255) DEFAULT NULL");
        $this->addSql("ALTER TABLE report_film CHANGE id_user id_user INT DEFAULT NULL, CHANGE id_film id_film INT DEFAULT NULL");
        $this->addSql("DROP INDEX email ON user");
        $this->addSql("ALTER TABLE user DROP email, DROP username, DROP password, DROP invitation_code, DROP picture_file");
        $this->addSql("ALTER TABLE film_today_vote CHANGE id id INT AUTO_INCREMENT NOT NULL, CHANGE id_film_today id_film_today INT DEFAULT NULL, CHANGE id_user id_user INT DEFAULT NULL, CHANGE vote_date vote_date DATE DEFAULT NULL");
        $this->addSql("ALTER TABLE video CHANGE timestamp timestamp DATETIME NOT NULL");
    }

    public function down(Schema $schema)
    {
        // this down() migration is autogenerated, please modify it to your needs
        $this->abortIf($this->connection->getDatabasePlatform()->getName() != "mysql");

        $this->addSql("CREATE TABLE cinema (id INT AUTO_INCREMENT NOT NULL, username LONGTEXT NOT NULL, usernameCanonical LONGTEXT NOT NULL, email LONGTEXT NOT NULL, password LONGTEXT NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET u$
        $this->addSql("DROP TABLE film_today");
        $this->addSql("DROP TABLE user1");
        $this->addSql("ALTER TABLE film_location CHANGE screening_description screening_description LONGTEXT NOT NULL");
        $this->addSql("ALTER TABLE film_today_vote CHANGE id id INT NOT NULL, CHANGE id_film_today id_film_today INT NOT NULL, CHANGE id_user id_user INT NOT NULL, CHANGE vote_date vote_date DATETIME NOT NULL");
        $this->addSql("ALTER TABLE job CHANGE id id INT UNSIGNED AUTO_INCREMENT NOT NULL, CHANGE cinema cinema INT UNSIGNED NOT NULL, CHANGE name name LONGTEXT DEFAULT NULL, CHANGE status status VARCHAR(255) NOT NULL");
        $this->addSql("ALTER TABLE report_film CHANGE id_user id_user INT NOT NULL, CHANGE id_film id_film INT NOT NULL");
        $this->addSql("CREATE INDEX id_user ON session (id_user)");
        $this->addSql("ALTER TABLE user ADD email VARCHAR(255) DEFAULT NULL, ADD username VARCHAR(255) DEFAULT NULL, ADD password LONGTEXT DEFAULT NULL, ADD invitation_code VARCHAR(255) DEFAULT NULL, ADD picture_file LONGTEXT DEFAULT $
        $this->addSql("CREATE UNIQUE INDEX email ON user (email)");
        $this->addSql("ALTER TABLE video CHANGE timestamp timestamp DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL");
    }
}

我认为这突出了同样的问题 - 用户实体未正确扩展。

2 个答案:

答案 0 :(得分:0)

这就是为什么doctrine:schema:update不建议用于生产的原因。有一种更好,更健壮的方式:DoctrineMigrationsBundle。由于您的数据库发生了很大的变化(即您的某些列只需要重命名,有些列是新的,需要填写等等),您应该在您的数据库上处理,而不是自动处理。使用Doctrine Migrations,您可以以健壮的方式执行此步骤。您可以尝试从diff自动生成迁移类,但最后我认为您必须根据需要修改生成的类。我已经通过一个新的symfony安装和一个扩展FOSUserBundle基类的裸用户类(只有id)为你创建了一个迁移类。

<?php
// app/DoctrineMigrations/Version20130701120836.php

namespace Application\Migrations;

use Doctrine\DBAL\Migrations\AbstractMigration,
    Doctrine\DBAL\Schema\Schema;

/**
 * Auto-generated Migration: Please modify to your need!
 */
class Version20130701120836 extends AbstractMigration
{
    public function up(Schema $schema)
    {
        // this up() migration is autogenerated, please modify it to your needs
        $this->abortIf($this->connection->getDatabasePlatform()->getName() != "mysql");

        $this->addSql("CREATE TABLE fos_user (id INT AUTO_INCREMENT NOT NULL, username VARCHAR(255) NOT NULL, username_canonical VARCHAR(255) NOT NULL, email VARCHAR(255) NOT NULL, email_canonical VARCHAR(255) NOT NULL, enabled TINYINT(1) NOT NULL, salt VARCHAR(255) NOT NULL, password VARCHAR(255) NOT NULL, last_login DATETIME DEFAULT NULL, locked TINYINT(1) NOT NULL, expired TINYINT(1) NOT NULL, expires_at DATETIME DEFAULT NULL, confirmation_token VARCHAR(255) DEFAULT NULL, password_requested_at DATETIME DEFAULT NULL, roles LONGTEXT NOT NULL COMMENT '(DC2Type:array)', credentials_expired TINYINT(1) NOT NULL, credentials_expire_at DATETIME DEFAULT NULL, UNIQUE INDEX UNIQ_957A647992FC23A8 (username_canonical), UNIQUE INDEX UNIQ_957A6479A0D96FBF (email_canonical), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB");

    }

    public function down(Schema $schema)
    {
        // this down() migration is autogenerated, please modify it to your needs
        $this->abortIf($this->connection->getDatabasePlatform()->getName() != "mysql");

        $this->addSql("DROP TABLE fos_user");
    }
}

现在,您可以将CREATE语句修改为alter table,修改现有的colums并添加new。然后你需要第二个语句来更新两个规范字段。它们只是原始列的小写版本。它们对登录很重要。

与文档不同,如果您希望保持最小稳定性,则需要在composer.json中使用这两行来安装它。

    "doctrine/migrations": "*@alpha",
    "doctrine/doctrine-migrations-bundle": "dev-master"

答案 1 :(得分:0)

好的,修好了。我有一个扩展用户实体的注册实体,并且在复制/粘贴后我在其上留下了一些“用户”注释,因此它认为存在重复。我现在可以正常更新数据库了。