[WIP] Feature schema management #1267
Conversation
|
Looks good so far. I added some minor change requests. |
|
|
||
| $column = $tableSchema->getColumn($name); | ||
| $column->setType(Type::getType($typeName)); | ||
| if ([] !== $options) { |
dmolineus
Jan 30, 2019
Contributor
Shouldn't the options not being always applied? What if I want to force having no options?
Shouldn't the options not being always applied? What if I want to force having no options?
discordier
Feb 1, 2019
Author
Member
You are aware that this is an empty check and only calls the setter if any option is to be set on the doctrine column?
You are aware that this is an empty check and only calls the setter if any option is to be set on the doctrine column?
dmolineus
Feb 1, 2019
Contributor
Yes. My questions relates to the case that the injected table schema already has the column defined with some options. What would happen if the option might have changed?
Maybe it does not happen in the intended use case of the helper trait but at least the behaviour should be documented.
Yes. My questions relates to the case that the injected table schema already has the column defined with some options. What would happen if the option might have changed?
Maybe it does not happen in the intended use case of the helper trait but at least the behaviour should be documented.
discordier
Feb 5, 2019
Author
Member
I still do not get you on this one.
Where shall the options change?
As soon as the column is in schema, the schema is the master source, as the attribute is schema aware and therefore reflects the desired state.
If you (as third party developer) want to change the options in the schema, it is up to you to register an own schema generator that will override the column data again (registered with lower priority than the stock generator).
You can see the generator concept somewhat like compiler passes being sequentially run.
This trait merely is a helper that abstracts the whole "loop over all tables and all attributes and configure only the ones of type x" into a single "configure column y of type x"
I still do not get you on this one.
Where shall the options change?
As soon as the column is in schema, the schema is the master source, as the attribute is schema aware and therefore reflects the desired state.
If you (as third party developer) want to change the options in the schema, it is up to you to register an own schema generator that will override the column data again (registered with lower priority than the stock generator).
You can see the generator concept somewhat like compiler passes being sequentially run.
This trait merely is a helper that abstracts the whole "loop over all tables and all attributes and configure only the ones of type x" into a single "configure column y of type x"
|
Change requests so far adressed. Next step is to integrate the schema updater in the backend and disable schema manipulation from legacy backend services for new attributes. |
| protected function configure() | ||
| { | ||
| parent::configure(); | ||
| $this->addOption('force', null, InputOption::VALUE_NONE, 'Perform the update'); |
richardhj
Feb 1, 2019
Member
why do you name the option "force" to perform the update.
why do you name the option "force" to perform the update.
discordier
Feb 1, 2019
Author
Member
Was "inherited" from doctrine:schema:upgrade, I am not yet confident on the naming and even functionality though.
Doctrine has the plain command which simply states: "Schema is not in sync" and then you cann optionally pass one of the following options:
--dump-sql Dumps SQL on the console to update - won't work for us, as not every schema is SQL.
--force Discouraged in Doctrine but executes the upgrades. This is the only way for our usecase as only the schema managers know how to manage their schema (especially if it is non SQL).
Was "inherited" from doctrine:schema:upgrade, I am not yet confident on the naming and even functionality though.
Doctrine has the plain command which simply states: "Schema is not in sync" and then you cann optionally pass one of the following options:
--dump-sqlDumps SQL on the console to update - won't work for us, as not every schema is SQL.--forceDiscouraged in Doctrine but executes the upgrades. This is the only way for our usecase as only the schema managers know how to manage their schema (especially if it is non SQL).
|
As discussed yesterday I made some tests to apply schema migration. I set up a simple test case (https://github.com/dmolineus/docker-migration-test). The test scenarios are far away from being complete, but right now there are several issues when migrating schemas if tables contain data Issues
Thoughts
Test output $ docker-compose run php vendor/bin/phpunit
Starting doctrine-migration-test_db_1 ... done
stty: standard input
PHPUnit 8.0.2 by Sebastian Bergmann and contributors.
SchemaMigrationTest
✓ change string column type [0.311s]
x change string column type [0.227s]
✓ change string column type [0.283s]
x change string column type [0.241s]
x change string column type [0.189s]
x null to not null [0.230s]
x null to not null [0.250s]
✓ unique index [0.279s]
x unique index [0.180s]
✓ unique index [0.292s]
x unique index [0.192s]
x unique index [0.207s]
Time: 2.95 seconds, Memory: 6.00MB
There were 8 failures:
1) SchemaMigrationTest::testChangeStringColumnType with data set #1 ('string', array(), 'decimal', array(0), array('foo', 123, 8, 12.3))
An exception occurred while executing 'ALTER TABLE test_table CHANGE test_column test_column NUMERIC(10, 0) DEFAULT '0' NOT NULL':
SQLSTATE[HY000]: General error: 1366 Incorrect DECIMAL value: '0' for column '' at row -1
/code/tests/SchemaMigrationTestCase.php:88
/code/tests/SchemaMigrationTest.php:17
2) SchemaMigrationTest::testChangeStringColumnType with data set #3 ('string', array(), 'smallint', array(0), array('foo', 123, 8, 12.3))
An exception occurred while executing 'ALTER TABLE test_table CHANGE test_column test_column SMALLINT DEFAULT 0 NOT NULL':
SQLSTATE[HY000]: General error: 1366 Incorrect integer value: 'foo' for column 'test_column' at row 1
/code/tests/SchemaMigrationTestCase.php:88
/code/tests/SchemaMigrationTest.php:17
3) SchemaMigrationTest::testChangeStringColumnType with data set #4 ('string', array(32), 'string', array(8), array('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'))
An exception occurred while executing 'ALTER TABLE test_table CHANGE test_column test_column VARCHAR(8) NOT NULL':
SQLSTATE[01000]: Warning: 1265 Data truncated for column 'test_column' at row 1
/code/tests/SchemaMigrationTestCase.php:88
/code/tests/SchemaMigrationTest.php:17
4) SchemaMigrationTest::testNullToNotNull with data set #0 ('string', array(false), 'string', array(), array('abs', 123, 12.3, null))
An exception occurred while executing 'ALTER TABLE test_table CHANGE test_column test_column VARCHAR(255) NOT NULL':
SQLSTATE[22004]: Null value not allowed: 1138 Invalid use of NULL value
/code/tests/SchemaMigrationTestCase.php:88
/code/tests/SchemaMigrationTest.php:43
5) SchemaMigrationTest::testNullToNotNull with data set #1 ('string', array(false), 'decimal', array(0), array(123, 12.3, null))
An exception occurred while executing 'ALTER TABLE test_table CHANGE test_column test_column NUMERIC(10, 0) DEFAULT '0' NOT NULL':
SQLSTATE[01000]: Warning: 1265 Data truncated for column 'test_column' at row 3
/code/tests/SchemaMigrationTestCase.php:88
/code/tests/SchemaMigrationTest.php:43
6) SchemaMigrationTest::testUniqueIndex with data set #1 ('string', array(), 'string', array(), array('abc', 'foo', 'foo'))
An exception occurred while executing 'CREATE UNIQUE INDEX UNIQ_FDF7294DEA8A8050 ON test_table (test_column)':
SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry 'foo' for key 'UNIQ_FDF7294DEA8A8050'
/code/tests/SchemaMigrationTestCase.php:88
/code/tests/SchemaMigrationTest.php:68
7) SchemaMigrationTest::testUniqueIndex with data set #3 ('decimal', array(), 'decimal', array(), array(1, 2, 1.0))
An exception occurred while executing 'CREATE UNIQUE INDEX UNIQ_FDF7294DEA8A8050 ON test_table (test_column)':
SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '1' for key 'UNIQ_FDF7294DEA8A8050'
/code/tests/SchemaMigrationTestCase.php:88
/code/tests/SchemaMigrationTest.php:68
8) SchemaMigrationTest::testUniqueIndex with data set #4 ('decimal', array(), 'decimal', array(), array(1, 2, 1.0, 1))
An exception occurred while executing 'CREATE UNIQUE INDEX UNIQ_FDF7294DEA8A8050 ON test_table (test_column)':
SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '1' for key 'UNIQ_FDF7294DEA8A8050'
/code/tests/SchemaMigrationTestCase.php:88
/code/tests/SchemaMigrationTest.php:68
FAILURES!
Tests: 12, Assertions: 48, Failures: 8. |
|
My considerations about the open todo how to intergrate the schema updater in the backend:
|
|
in additional to #1267 (comment)
|
Before only slugs were read
Hotfix release 2.1.4 - Read parameters from the get section before ths slug parameters are read - Ignore rendering of internal attributes in show
This will add the remaining attributes (all non `ISchemaManagedAttribute` or `IInternal`) to the legacy schema.
a87324b
to
1599dbb
Description
As we have several problems with strict mode and therefore need to upgrade the database, here is a first throw at schema abstraction.
Companion PRs:
TODO: