首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Yii2:支持MySQL和PostgreSQL

Yii2:支持MySQL和PostgreSQL
EN

Stack Overflow用户
提问于 2019-01-09 09:35:49
回答 2查看 457关注 0票数 0

我的Yii2应用程序应该允许客户使用MySQL或PostgreSQL作为数据库后端。因此,我需要编写两个数据库运行的代码。

我开始支持MySQL,需要对特定于MySQL的代码进行筛选,例如在迁移中:

代码语言:javascript
复制
public function up() {
    $this->execute('ALTER SCHEMA DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci');
    $this->execute('ALTER SCHEMA CHARACTER SET utf8 COLLATE utf8_general_ci');
    $this->createTable('user', [ 
            'id' => $this->primaryKey(),
            ... 
        ],
       'CHARACTER SET utf8 COLLATE utf8_general_ci ENGINE=InnoDB'
    );
}

如何重写这段代码?

是否有回购解决了这一问题?MySQL和PostgreSQL兼容性的最佳实践是什么?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-01-09 12:12:21

如果我正确地理解了您所说的编写迁移,它可以根据当前选定的数据库或目标数据库来处理特定于db的关键字或函数,那么您可能必须为此创建自己的逻辑,以支持迁移。

我使用下面的类作为基本迁移类,并为tableOptions和删除列约束扩展该类的迁移。您可以根据需要对其进行升级并添加必要的操作/功能。但是它可以创建实现您所要求的内容的逻辑。

代码语言:javascript
复制
<?php

namespace console\migrations;
use Yii;
class Migration extends \yii\db\Migration
{

    /**
     * @var string
     */
    protected $tableOptions;

    /**
     * @var string
     */
    protected $restrict = 'RESTRICT';

    /**
     * @var string
     */
    protected $cascade = 'CASCADE';

    /**
     * @var string
     */
    protected $noAction = 'NO ACTION';

    /**
     * @var mixed
     */
    protected $dbType;

    /**
     * @inheritdoc
     */
    public function init()
    {
        parent::init();

        switch ($this->db->driverName) {
            case 'mysql':
                $this->tableOptions = 'CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE=InnoDB';
                $this->dbType = 'mysql';
                break;
            case 'pgsql':
                $this->tableOptions = null;
                $this->dbType = 'pgsql';
                break;
            case 'dblib':
            case 'mssql':
            case 'sqlsrv':
                $this->restrict = 'NO ACTION';
                $this->tableOptions = null;
                $this->dbType = 'sqlsrv';
                break;
            default:
                throw new \RuntimeException('Your database is not supported!');
        }
    }

    /**
     * Drops the constraints for the given column
     *
     * @param string $table  the table name
     * @param string $column the column name
     *
     * @return null
     */
    public function dropColumnConstraints($table, $column)
    {
        $table = Yii::$app->db->schema->getRawTableName($table);
        $cmd = Yii::$app->db->createCommand(
            'SELECT name FROM sys.default_constraints
            WHERE parent_object_id = object_id(:table)
            AND type = \'D\' AND parent_column_id = (
                SELECT column_id
                FROM sys.columns
                WHERE object_id = object_id(:table)
                and name = :column
            )', [':table' => $table, ':column' => $column]
        );

        $constraints = $cmd->queryAll();
        foreach ($constraints as $c) {
            $this->execute('ALTER TABLE ' . Yii::$app->db->quoteTableName($table) . ' DROP CONSTRAINT ' . Yii::$app->db->quoteColumnName($c['name']));
        }
    }

}
票数 1
EN

Stack Overflow用户

发布于 2019-01-09 11:23:10

我不太熟悉Postgre,但是从应用程序高级的基本迁移的外观来看,您可以检查driverName并在此基础上创建不同的逻辑。

迁移文件

代码语言:javascript
复制
$tableOptions = null;
if ($this->db->driverName === 'mysql') {
    $tableOptions = 'CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE=InnoDB';
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54106977

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档