【问题标题】:CakePHP 3: Best Practice for Temporary SQL TablesCakePHP 3:临时 SQL 表的最佳实践
【发布时间】:2018-08-29 17:55:57
【问题描述】:

亲爱的 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”不存在

求助,我卡住了。 :(

【问题讨论】:

    标签: mysql cakephp cakephp-3.0 temp-tables


    【解决方案1】:

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

    表类基本上应该像往常一样配置,你应该在应用程序访问它之前创建临时数据库表。您可以手动编写原始表创建 SQL,也可以从支持临时表的 \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);
    

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

    $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`)
        )'
    ]
    

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

    另见

    【讨论】:

    • 天哪,尤其是最后一部分,即使我没有错过setTemporary()的存在,也很难环绕。非常感谢!我希望临时表的实际表创建在某个时候能够集成到 CakePHP 的完全自动化的头脑中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-05
    • 1970-01-01
    • 1970-01-01
    • 2016-07-06
    • 2013-04-06
    • 1970-01-01
    相关资源
    最近更新 更多