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

CakePHP 3: Best Practice for Temporary SQL Tables

尊敬的 CakePHP 3 开发人员,

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

我在src/Model/Table/TempItemsTable.php中准备了Table:

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 所需的 table 架构的想法来自一个可能不相关的 documentation for Test Fixtures

但是我如何告诉 CakePHP 不要在数据库中寻找实际的 table? 未注释的行 $this->setTable(null); 是我在这方面的糟糕尝试,据说与 the right way in earlier versions of CakePHP, but according to version 3.x documentation, setTable() doesn't accept null, while table() 类似,但它从 3.4 开始被弃用并且也没有改变任何东西。

最后,当然,当我尝试通过 $temp = TableRegistry::get('TempItems');:

在控制器中访问这个 "table" 时,我得到了这个异常

SQLSTATE[42S02]: Base table or view not found: 1146 Table 'mydatabase.temp_items' doesn't exist

救命,我卡住了。 :(

不需要告诉它 而不是 寻找 table,实际上这与你想要做的相反,因为你最终想要访问它。

table class 基本上应该像往常一样配置,您应该在应用程序访问它之前创建临时数据库 table。您可以手动编写原始 table 创建 SQL,或者从支持临时 tables.

\Cake\Database\Schema\TableSchema 实例生成它

您可以显式创建模式对象:

$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);

或者让 table 对象生成它,使用您的字段定义数组:

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

然后您可以从架构对象生成 table 创建 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 将是创建 table 所需的 SQL 命令数组,类似于:

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

请注意,如果您不将模式分配给 table 对象,您可能 运行 会遇到缓存问题,因为当您更改 [=50] 时缓存的模式将不再匹配=]定义并且不清除缓存。

另见