CakePHP 3:临时SQL表的最佳实践

时间:2018-03-20 19:06:46

标签: mysql cakephp cakephp-3.0 temp-tables

亲爱的CakePHP 3开发者,

我希望在CakePHP 3.4.13项目中使用SQL's Temporary Tables来运行一个脚本。通过Cake的文档,似乎没有直接的方法告诉CakePHP我的愿望。那么我最好怎么做呢?

我已在src/Model/Table/TempItemsTable.php中准备了一张表:

namespace App\Model\Table;
use Cake\ORM\Table;

class TempItemsTable extends Table
{
    public $fields = [
        'id' => ['type' => 'integer'],
        'con' => ['type' => 'string', 'length' => 255, 'null' => false],
        '_constraints' => [
            'primary' => ['type' => 'primary', 'columns' => ['id']]
        ]
    ];
    public function initialize(array $config)
    {
        // $this->setTable(null);
    }
}

使用$ fields来告诉CakePHP所需的表模式的想法来自可能不相关的documentation for Test Fixtures

但是如何告诉CakePHP不要在数据库中查找实际的表? 取消注释的行$this->setTable(null);是我的不良尝试,据说与the right way in earlier versions of CakePHP类似,但根据版本3.x文档,setTable()不接受null },虽然table()有,但是从3.4开始就被弃用了,也没有改变任何内容。

最后,当然,一旦我尝试访问这个"表"我就会得到这个例外。在控制器中通过$temp = TableRegistry::get('TempItems');

  

SQLSTATE [42S02]:未找到基表或视图:1146表' mydatabase.temp_items'不存在

帮助,我被困住了。 :(

1 个答案:

答案 0 :(得分:1)

没有必要告诉寻找表格,实际上这与您想要做的事情相反,因为您最终想要访问它

表类基本上应该照常配置,并且应该在应用程序访问它之前创建临时数据库表。您可以手动编写原始表创建SQL,也可以从支持临时表的\Cake\Database\Schema\TableSchema实例生成SQL。

您可以显式创建架构对象:

$schema = new \Cake\Database\Schema\TableSchema('temp_items');
$schema
    ->addColumn('id', ['type' => 'integer'])
    ->addColumn('con', ['type' => 'string', 'length' => 255, 'null' => false])
    ->addConstraint('primary', ['type' => 'primary', 'columns' => ['id']])
    ->setTemporary(true);

$TableObject->setSchema($schema);

或让表对象使用字段定义数组生成它:

$TableObject->setSchema($TableObject->fields);
$schema = $TableObject->getSchema()->setTemporary(true);

然后,您可以从架构对象生成表创建SQL,并针对数据库运行它:

$connection = $TableObject->getConnection();
$queries = $schema->createSql($connection);

$connection->transactional(
    function (\Cake\Database\Connection $connection) use ($queries) {
        foreach ($queries as $query) {
            $stmt = $connection->execute($query);
            $stmt->closeCursor();
        }
    }
);

$queries将是创建表所需的SQL命令数组,类似于:

[
    'CREATE TEMPORARY TABLE `temp_items` (
        `id` INTEGER AUTO_INCREMENT,
        `con` VARCHAR(255) NOT NULL,
        PRIMARY KEY (`id`)
    )'
]

请注意,如果您没有将架构分配给表对象,则可能会遇到缓存问题,因为当您更改表定义并且不清除缓存时,缓存的架构将不再匹配。

另见