From: fomichev Date: Tue, 5 May 2026 10:24:53 +0000 (+0300) Subject: llm verification migration fix X-Git-Url: https://gitweb.erp-flowers.ru/?a=commitdiff_plain;h=b28f52c2d757dd36898dd41273090cca31dfcd23;p=erp24_rep%2Fyii-erp24%2F.git llm verification migration fix --- diff --git a/erp24/migrations/m260417_000001_create_products_1c_automark_predictions.php b/erp24/migrations/m260417_000001_create_products_1c_automark_predictions.php index 376a83b3..3bb225e7 100644 --- a/erp24/migrations/m260417_000001_create_products_1c_automark_predictions.php +++ b/erp24/migrations/m260417_000001_create_products_1c_automark_predictions.php @@ -6,39 +6,115 @@ use yii\db\Migration; class m260417_000001_create_products_1c_automark_predictions extends Migration { + public const TABLE_NAME = 'erp24.products_1c_automark_predictions'; + public const PRODUCTS_1C_TABLE = 'erp24.products_1c'; + public const INDEX_PRODUCT_ID = 'idx_automark_product_id'; + public const INDEX_STATUS = 'idx_automark_status'; + public const FK_PRODUCT = 'fk_automark_product'; + public function safeUp(): void { - $this->createTable('products_1c_automark_predictions', [ - 'id' => $this->primaryKey(), - 'product_id' => $this->string(36)->notNull(), - 'category' => $this->string(255)->null(), - 'subcategory' => $this->string(255)->null(), - 'species' => $this->string(255)->null(), - 'sort' => $this->string(255)->null(), - 'type' => $this->string(255)->null(), - 'size' => $this->integer()->null(), - 'color' => $this->string(255)->null(), - 'confidence' => $this->float()->notNull(), - 'method' => $this->string(50)->notNull(), - 'status' => $this->smallInteger()->notNull()->defaultValue(0), - 'approved_by' => $this->integer()->null(), - 'created_at' => $this->timestamp()->notNull()->defaultExpression('CURRENT_TIMESTAMP'), - 'updated_at' => $this->timestamp()->null(), - ]); - - $this->createIndex('idx_automark_product_id', 'products_1c_automark_predictions', 'product_id'); - $this->createIndex('idx_automark_status', 'products_1c_automark_predictions', 'status'); - $this->addForeignKey( - 'fk_automark_product', - 'products_1c_automark_predictions', 'product_id', - 'products_1c', 'id', - 'CASCADE', 'CASCADE' - ); + $tableSchema = $this->db->getTableSchema(self::TABLE_NAME); + if (!isset($tableSchema)) { + $this->createTable(self::TABLE_NAME, [ + 'id' => $this->primaryKey(), + 'product_id' => $this->string(36)->notNull(), + 'category' => $this->string(255)->null(), + 'subcategory' => $this->string(255)->null(), + 'species' => $this->string(255)->null(), + 'sort' => $this->string(255)->null(), + 'type' => $this->string(255)->null(), + 'size' => $this->integer()->null(), + 'color' => $this->string(255)->null(), + 'confidence' => $this->float()->notNull(), + 'method' => $this->string(50)->notNull(), + 'status' => $this->smallInteger()->notNull()->defaultValue(0), + 'approved_by' => $this->integer()->null(), + 'created_at' => $this->timestamp()->notNull()->defaultExpression('CURRENT_TIMESTAMP'), + 'updated_at' => $this->timestamp()->null(), + ]); + } + + $tableSchema = $this->db->getTableSchema(self::TABLE_NAME); + $productsSchema = $this->db->getTableSchema(self::PRODUCTS_1C_TABLE); + if (!isset($tableSchema) || !isset($productsSchema)) { + return; + } + + if (!$this->hasIndex(self::INDEX_PRODUCT_ID)) { + $this->createIndex(self::INDEX_PRODUCT_ID, self::TABLE_NAME, 'product_id'); + } + + if (!$this->hasIndex(self::INDEX_STATUS)) { + $this->createIndex(self::INDEX_STATUS, self::TABLE_NAME, 'status'); + } + + if (!$this->hasForeignKey(self::FK_PRODUCT)) { + $this->addForeignKey( + self::FK_PRODUCT, + self::TABLE_NAME, + 'product_id', + self::PRODUCTS_1C_TABLE, + 'id', + 'CASCADE', + 'CASCADE' + ); + } } public function safeDown(): void { - $this->dropForeignKey('fk_automark_product', 'products_1c_automark_predictions'); - $this->dropTable('products_1c_automark_predictions'); + $tableSchema = $this->db->getTableSchema(self::TABLE_NAME); + if (!isset($tableSchema)) { + return; + } + + if ($this->hasForeignKey(self::FK_PRODUCT)) { + $this->dropForeignKey(self::FK_PRODUCT, self::TABLE_NAME); + } + + if ($this->hasIndex(self::INDEX_PRODUCT_ID)) { + $this->dropIndex(self::INDEX_PRODUCT_ID, self::TABLE_NAME); + } + + if ($this->hasIndex(self::INDEX_STATUS)) { + $this->dropIndex(self::INDEX_STATUS, self::TABLE_NAME); + } + + $this->dropTable(self::TABLE_NAME); + } + + private function hasIndex(string $indexName): bool + { + return (new \yii\db\Query()) + ->from('pg_indexes') + ->where([ + 'schemaname' => $this->getSchemaName(self::TABLE_NAME), + 'indexname' => $indexName, + ]) + ->exists($this->db); + } + + private function hasForeignKey(string $constraintName): bool + { + return (new \yii\db\Query()) + ->from('information_schema.table_constraints') + ->where([ + 'table_schema' => $this->getSchemaName(self::TABLE_NAME), + 'table_name' => $this->getPureTableName(self::TABLE_NAME), + 'constraint_name' => $constraintName, + 'constraint_type' => 'FOREIGN KEY', + ]) + ->exists($this->db); + } + + private function getSchemaName(string $tableName): string + { + return explode('.', $tableName, 2)[0]; + } + + private function getPureTableName(string $tableName): string + { + return explode('.', $tableName, 2)[1] ?? $tableName; } } diff --git a/erp24/migrations/m260430_000001_add_llm_fields_to_automark_predictions.php b/erp24/migrations/m260430_000001_add_llm_fields_to_automark_predictions.php index f0918610..74a452ad 100644 --- a/erp24/migrations/m260430_000001_add_llm_fields_to_automark_predictions.php +++ b/erp24/migrations/m260430_000001_add_llm_fields_to_automark_predictions.php @@ -6,35 +6,92 @@ use yii\db\Migration; class m260430_000001_add_llm_fields_to_automark_predictions extends Migration { + public const TABLE_NAME = 'erp24.products_1c_automark_predictions'; + public const INDEX_LLM_VERDICT = 'idx_automark_llm_verdict'; + public function safeUp(): void { - $this->addColumn( - 'products_1c_automark_predictions', - 'llm_verdict', - $this->string(20)->null()->defaultValue(null)->after('method') - ); - $this->addColumn( - 'products_1c_automark_predictions', - 'llm_verified_at', - $this->timestamp()->null()->defaultValue(null)->after('llm_verdict') - ); - $this->addColumn( - 'products_1c_automark_predictions', - 'llm_comment', - $this->string(500)->null()->defaultValue(null)->after('llm_verified_at') - ); - $this->createIndex( - 'idx_automark_llm_verdict', - 'products_1c_automark_predictions', - 'llm_verdict' - ); + $tableSchema = $this->db->getTableSchema(self::TABLE_NAME); + if (!isset($tableSchema)) { + return; + } + + if (!$this->hasColumn('llm_verdict')) { + $this->addColumn( + self::TABLE_NAME, + 'llm_verdict', + $this->string(20)->null()->defaultValue(null)->after('method') + ); + } + + if (!$this->hasColumn('llm_verified_at')) { + $this->addColumn( + self::TABLE_NAME, + 'llm_verified_at', + $this->timestamp()->null()->defaultValue(null)->after('llm_verdict') + ); + } + + if (!$this->hasColumn('llm_comment')) { + $this->addColumn( + self::TABLE_NAME, + 'llm_comment', + $this->string(500)->null()->defaultValue(null)->after('llm_verified_at') + ); + } + + if (!$this->hasIndex(self::INDEX_LLM_VERDICT)) { + $this->createIndex( + self::INDEX_LLM_VERDICT, + self::TABLE_NAME, + 'llm_verdict' + ); + } } public function safeDown(): void { - $this->dropIndex('idx_automark_llm_verdict', 'products_1c_automark_predictions'); - $this->dropColumn('products_1c_automark_predictions', 'llm_comment'); - $this->dropColumn('products_1c_automark_predictions', 'llm_verified_at'); - $this->dropColumn('products_1c_automark_predictions', 'llm_verdict'); + $tableSchema = $this->db->getTableSchema(self::TABLE_NAME); + if (!isset($tableSchema)) { + return; + } + + if ($this->hasIndex(self::INDEX_LLM_VERDICT)) { + $this->dropIndex(self::INDEX_LLM_VERDICT, self::TABLE_NAME); + } + + if ($this->hasColumn('llm_comment')) { + $this->dropColumn(self::TABLE_NAME, 'llm_comment'); + } + + if ($this->hasColumn('llm_verified_at')) { + $this->dropColumn(self::TABLE_NAME, 'llm_verified_at'); + } + + if ($this->hasColumn('llm_verdict')) { + $this->dropColumn(self::TABLE_NAME, 'llm_verdict'); + } + } + + private function hasColumn(string $columnName): bool + { + $tableSchema = $this->db->getTableSchema(self::TABLE_NAME); + return isset($tableSchema?->columns[$columnName]); + } + + private function hasIndex(string $indexName): bool + { + return (new \yii\db\Query()) + ->from('pg_indexes') + ->where([ + 'schemaname' => $this->getSchemaName(self::TABLE_NAME), + 'indexname' => $indexName, + ]) + ->exists($this->db); + } + + private function getSchemaName(string $tableName): string + { + return explode('.', $tableName, 2)[0]; } }