在TYPO3 11的扩展升级向导中重命名数据库字段。

huangapple go评论52阅读模式
英文:

rename database field in upgrade wizard of an extension in TYPO3 11

问题

我有一个升级向导(TYPO3 11),用于更改表格数据。这是通过querybuilder完成的:

$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
					->getQueryBuilderForTable('tt_content');

$queryBuilder
	->update('tt_content')
	->set('CType', 'newCType')
	->where($queryBuilder
				->expr()
				->eq('CType', $queryBuilder->createNamedParameter('oldCType')))
	->execute();

但我还需要在表格中重命名一个字段:

ALTER TABLE tt_content RENAME COLUMN tx_myext_old_field TO tx_myext_new_field;

我找不到使用querybuilder执行此操作的文档或示例。

英文:

I have an upgrade wizard (TYPO3 11) which changes the data of a table.
This is done with the querybuilder:

$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
					->getQueryBuilderForTable('tt_content');

$queryBuilder
	->update('tt_content')
	->set('CType', 'newCType')
	->where($queryBuilder
				->expr()
				->eq('CType',$queryBuilder->createNamedParameter('oldCType')))
	->execute();

But I also need to rename a field in a table:

ALTER TABLE tt_content RENAME COLUMN tx_myext_old_field TO tx_myext_new_field;

I can't find any documentation or example of doing this with the querybuilder.

答案1

得分: 0

提供ext_tables.sql文件是标准的做法。TYPO3会读取该文件以构建一个虚拟的"数据库模式",描述了数据库应该如何看起来。

数据库模式分析器会提供相关信息,并建议数据库更改。

您可以向升级向导添加一个必须保持最新的数据库约束,以确保字段已更改。

处理DTL是一项特殊任务,您需要自己提供相应的查询...而不同的DBMS系统需要不同的查询。因此,建议使用标准方式。

平台/驱动程序可能具有一些通用的辅助方法,可以提供一些原生SQL部分来执行类似的操作。可能可以基于SchemaMigrator或SchemaManger等提供自定义内容,但这是底层的操作。

doctrine/dbal本身并没有提供这些DTL作为API。查询构建器也不适用于这种低级操作。那不是用于这种任务的正确工具。

您也可以通过仅提供表名和要更改的字段的列定义来更改核心表的列。

官方方式是使用ext_tables.sql和数据库模式分析器来处理这个问题。

参考链接: https://docs.typo3.org/m/typo3/reference-coreapi/main/en-us/ExtensionArchitecture/FileStructure/ExtTablesSql.html

英文:

The normal way woult be to provide a ext_tables.sql in your extension. This is read by TYPO3 to build a virtual "database scheme" how it should look.

The database schema analyser will than provide the information, and database alteration are suggested.

You could add a database must be up to date constraint to your upgrade wizard, that way it is ensured that the field is changed.

DTL is a special task, and you have to provide the correspinng queries yourself ... which are different for different dbms systems. So using the normal way would be recommended.

The platform/driver may have some generig helper methods providing some native sql parts for doing stuffs like that. The may be possible to provide custom stuff based on SchemaMigrator or SchemaManger etc - but thats low-level stuff.

doctrine/dbal directly do not really provide these DTL as API. And the querybuilder is not meant to be used for that low level stuff at all. That's the wrong tool for such tasks.

You can also change columns of core tables that way, by providing simply the table name and the column defintion only for the field you want to change.

The official way is to handle this with ext_tables.sql and the database schema analyser.

See: https://docs.typo3.org/m/typo3/reference-coreapi/main/en-us/ExtensionArchitecture/FileStructure/ExtTablesSql.html

答案2

得分: 0

重命名列的概念无法工作:在安装扩展时,所有新字段都会生成(或者在composer模式下应该生成)。由于扩展应该与新列一起工作,它们已经被定义。在升级向导之前,无法重命名列,因为这些列已经存在,这会阻止重命名。

最后,我通过复制内容来增强更新查询,如下所示:

$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
                    ->getQueryBuilderForTable('tt_content');

$queryBuilder
    ->update('tt_content')
    ->set('CType', 'newCType')
    ->set('tx_myext_newfield1', $queryBuilder->quoteIdentifier('tx_myext_oldfield1'), false)
    ->set('tx_myext_newfield2', $queryBuilder->quoteIdentifier('tx_myext_oldfield2'), false)
    ->where($queryBuilder
                ->expr()
                ->eq('CType', $queryBuilder->createNamedParameter('oldCType')))
    ->executeStatement();
英文:

The concept of renaming a column could not work:
On installing the extension all new fields are generated (or should be generated if in composer mode). And as the extension should work with the new columns they are already defined.
And before the upgrade wizard could rename a column these columns are existent already which prevents a rename.

In the end I do a content copy enhancing the update query like this:

$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
                    ->getQueryBuilderForTable('tt_content');

$queryBuilder
    ->update('tt_content')
    ->set('CType', 'newCType')
    ->set('tx_myext_newfield1',$queryBuilder->quoteIdentifier('tx_myext_oldfield1'),false)
    ->set('tx_myext_newfield2',$queryBuilder->quoteIdentifier('tx_myext_oldfield2'),false)
    ->where($queryBuilder
                ->expr()
                ->eq('CType',$queryBuilder->createNamedParameter('oldCType')))
    ->executeStatement();

huangapple
  • 本文由 发表于 2023年2月6日 21:03:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/75361669.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定