问题描述
概念:
我有一个任务,它在数据库中导入一些数据。数据库架构可以随时更改,因为它已导出到文件夹。所以我必须读取数据库文件并创建结构。我想用 TYPO3 API 来做。在 TYPO3 9 之前,我会做这样的事情:
$sqlQueries = explode(';',file_get_contents(dirname(__FILE__) . DIRECTORY_SEParaTOR . 'myFile.sql'));
foreach ($sqlQueries as $sqlQuery) {
$sqlQuery = trim($sqlQuery);
if (!empty($sqlQuery) && $this->db instanceof DatabaseConnection && method_exists($this->db,'sql_query')) {
$this->db->sql_query($sqlQuery);
}
}
我如何使用 TYPO3 10 做到这一点?
最好的问候
解决方法
TYPO3 10 已经有这样的功能,你可以在维护模块下找到它 分析数据库结构。感谢 Mathias Brodala 我找到了我的解决方案。 (它总是可以改进的)。
在您的任务中,您调用 SqlReader 类以从 SQL 文件中提取语句。使用命名空间如下(截至 TYPO3 10)
use TYPO3\CMS\Core\Database\Schema\SqlReader;
现在我们有两个问题
- TYPO3 评估和执行的 SQL 仅限于模式。对于内容更改,您需要第三方库/工具。
- 它只创建表,默认情况下不会删除它们。
第一个“问题”是说您只能执行数据库结构更改,而不能更改其中的内容。为此,可以使用 QueryBuilder。
第二个问题是 SqlReader 类中的 getCreateTableStatementArray 函数执行以下操作:
return $this->getStatementArray($dumpContent,'^CREATE TABLE');
这会调用 getStatementArray 函数,它只返回 CREATE TABLE 命令。所以如果你在 SQL 文件中有一个 DROP TABLE 命令,它不会被考虑在内。为此,我们需要为 getCreateTableStatementArray 创建我们自己的函数。所以在你的任务中,创建这个函数:
/**
* @param string $dumpContent
* @return array
*/
public function getCreateTableStatementArray(string $dumpContent): array
{
$sqlReader = GeneralUtility::makeInstance(SqlReader::class);
return $sqlReader->getStatementArray($dumpContent);
}
这样,TYPO3 将不会按命令名称评估语句,而是会获取 sql 文件中可用的所有命令。
既然我们已经这样做了,我们需要将语句传递到我们的自定义函数中进行解析。所以在你的代码中你会得到文件的内容。我是这样的:
/**
* @return bool
* @throws \Exception
*/
public function execute()
{
...
$this->createTableStructure();
...
}
protected function createTableStructure()
{
$connectionPool = GeneralUtility::makeInstance(ConnectionPool::class);
$sqlStatements = $this->getCreateTableStatementArray(file_get_contents(__DIR__ . DIRECTORY_SEPARATOR . 'myFile.sql'));
foreach ($sqlStatements as $sqlStatement) {
if (strpos($sqlStatement,' CHARSET=utf8') !== false) {
$sqlStatement = str_replace(" DEFAULT CHARSET=utf8","",$sqlStatement);
}
$connection = $connectionPool->getConnectionByName('Default');
try {
$connection->executeUpdate($sqlStatement);
} catch (DBALException $e) {
//Your log here
}
}
}
对于这部分,我收到一个错误,即 TYPO3 无法读取 DEFAULT 属性,因此我不得不将其删除。
if (strpos($sqlStatement,' CHARSET=utf8') !== false) {
$sqlStatement = str_replace(" DEFAULT CHARSET=utf8",$sqlStatement);
}
这在 SQL 文件中看起来像这样:
DROP TABLE IF EXISTS `myTable`;
CREATE TABLE IF NOT EXISTS `myTable` (
`myColumn1` int(10) NOT NULL DEFAULT '0',`myColumn2` varchar(255) DEFAULT NULL,`myColumn3` varchar(255) DEFAULT NULL,`myColumn4` date DEFAULT NULL,`myColumn5` varchar(255) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
希望对你有帮助!
最好的问候