2

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

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

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

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

我去更新与教义模式:模式:更新--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 的建议下,我安装了学说迁移包并尝试创建一个迁移。它生成以下内容

/**
 * 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");
    }
}

我认为这突出了同样的问题——用户实体没有被正确扩展。

4

2 回答 2

0

That's the reason why doctrine:schema:update is not recommended for production. There is a much better and robust way: the DoctrineMigrationsBundle. As you have a heavy change in your database (i.e. your some columns need only renames, some are new, they need to be filled, etc.) you should take care of it on yours and not automatically. With the Doctrine Migrations you can do this step in a robust way. You can try to generate your migrations class automatically from the diff, but in the end I think you must modify the generated class to your needs. I've made you a migrations class from a fresh symfony installation and with a naked user class (only id) extending the FOSUserBundle base class.

<?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");
    }
}

Now you can modify the CREATE statement to a alter table, modifying your existing colums and add new. Then you need a second statement to UPDATE the two canonical fields. they are simply lower case versions of their original columns. And they are important for login.

Unlikely to the documentation, you need this two lines in your composer.json to install it, if you want to remain your minimun-stability to stable.

    "doctrine/migrations": "*@alpha",
    "doctrine/doctrine-migrations-bundle": "dev-master"
于 2013-07-01T10:16:41.307 回答
0

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

于 2013-07-01T13:29:25.610 回答