After updating to Ubercart 8.x-4.x-dev I am receiving the following error in reports:

ENTITY/FIELD DEFINITIONS
Mismatched entity and/or field definitions
The following changes were detected in the entity type and field definitions.
Payment receipt
The Payment method field needs to be updated.

Here is how Drush responds when I try to update the entity:

>drush entup
The following updates are pending:

uc_payment_receipt entity type :
The Payment method field needs to be updated.
Do you wish to run all pending updates? (y/n): y
Drupal\Core\Entity\Exception\FieldStorageDefinitionUpdateForbiddenException:[err or]
The SQL storage cannot change the schema for an existing field
(method in uc_payment_receipt entity) with data. in
Drupal\Core\Entity\Sql\SqlContentEntityStorageSchema->updateSharedTableSchema()
(line 1432 of
/home/------/public_html/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStora geSchema.php).
Failed: [error]
Drupal\Core\Entity\Exception\FieldStorageDefinitionUpdateForbiddenException:
!message in
Drupal\Core\Entity\Sql\SqlContentEntityStorageSchema->updateSharedTableSchema ()
(line 1432 of
/home/------/public_html/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStora geSchema.php).
Cache rebuild complete. [ok]
Finished performing updates. [ok]

Comments

frednwright created an issue. See original summary.

TR’s picture

Status: Active » Closed (won't fix)

https://www.google.com/search?q=The+SQL+storage+cannot+change+the+schema...

This is a 'feature' of Drupal. Migrating old content to new content after an entity schema change is not a trivial thing, so during development (meaning alpha releases and even beta releases for core) Drupal policy is we don't write update functions to do this as it would involve a lot of extra work that is not easily testable (you only do the upgrade once ...) and is not applicable to most users. Once we have a stable release that's another matter - we always write update functions to move from stable release to the next stable release.

So short answer, the easiest way to fix this is to uninstall Ubercart and then reinstall. (You may be able to get away with just uninstalling/reinstalling the uc_payment module, you could try that first.) But if you have some existing data you really don't want to lose, then this can be fixed manually by poking into the DB and messing with the configuration, or even by writing your own update function - see the above link for ideas.

frednwright’s picture

TR,

Once again many thanks for your response, and many thanks for your commitment to Ubercart.

I'm working with a SQL developer to write some custom Ubercart reports - specifically reports that will list orders as well as attributes for each product (similar to the Who Bought What module). Can you tell me if Ubercart 4 has changed significantly with regard to the tables for product attributes?

TR’s picture

No, the product attribute stuff is virtually unchanged.

I strongly recommend you create your reports with Views, as we are trying to switch all Ubercart from custom query code to Views. So the uc_reports module will be going away in D8 as well as any hooks associated with it.

There is at least one open issue in this queue that has some proposed Views integrations for attributes #895236: Expose attributes to view, which might be useful to you.

Kalorlo’s picture

Status: Closed (won't fix) » Active

Is there any chance of more information about how to resolve this? I was using 8.x-4.0-alpha5 because it has been the only existing release for Drupal 8 for a year and a half. I tried updating to 8.x-4.x-dev tonight to hopefully have the ability to make shipping types made visible by Rules, as currently I just have to leave them all visible and hope the customer picks a relevant one, and ran into this.

I've put the alpha back for the time being, as it is for a live site.

I'm happy with updating SQL databases directly if I know what needs updating.

(If anyone else was looking up how to actually disable modules in D8 after this, see https://www.drupal.org/forum/support/upgrading-drupal/2014-03-24/why-can... and you need to go to admin/modules/uninstall)

I've been looking through the linked google results and haven't found anything useful yet - I'm mostly getting patches for specific other modules.

TR’s picture

The error says that it's the "method" field of the uc_payment_receipt entity that is the problem.

The "method" field was changed from an entity_reference to a string in issue #2788963: Call to a member function label() on null, which was committed after alpha5 was released. The core Drupal field update won't allow you to change a datatype for an entity field if there is already data in that field.

So at a minimum you will have to change the method column in the {uc_payment_receipts} table to be a varchar(255) (I think the old value used by entity reference was int(10)). Then you will have to modify the data in that column to be method ids, which are the ids shown in the annotation of the payment method plugins. For example, "check" if you're using the Check payment method, paypal_wps for PayPal WPS, etc. If you only accept one payment method then this should be easy, but if you have more than one payment method then you will have to figure out which rows should get which values.

You will probably also have to clear your caches first. Then I don't know how core Drupal detects that the schema has changes, so I don't know if it will still think there's an update to perform. If it's just parsing the code, looking at the schema definition and comparing it to the database schema, then I think the changes above will be enough to fool core into thinking that the schema doesn't need updating and you will be done. I would try examining old orders and maybe deleting or adding payments to an old order, just to check to see that all your old data is still usable.

Kalorlo’s picture

Thanks TR!

method in uc_payment_receipts is already a varchar(255) for me, and the values for existing orders are "paypal_wps" (only payment option). Collation is ascii_general_ci, Attributes is empty, Null is Yes, Default NULL, Comments "The ID of the target entity." and Extra is empty The index keyname is uc_payment_receipt_field__method__target_id

I can try creating a dev site with the dev versions and seeing what the database looks like there.

TR’s picture

Status: Active » Closed (won't fix)
roblog’s picture

I've just run into this problem. I was able to fix it by updating the 'value' field for two entries in the key_value table of the database. The two entries were:
uc_payment_receipt.field_storage_definitions
uc_payment_receipt.field_schema_data.method

I obtained the correct values by installing the Dev version of the module in another site which didn't already have Ubercart installed, and copied the two values over from this site to the broken site's database.

hash6’s picture

I was able to fix it using the steps given below for Drupal 8.9.2 and Ubercart 4.x-dev

1. Clone uc_payment_receipts table using query given below
2. Set the uc_payment_receipts method column to null using the query given below
3. Install devel_entity_updates module using composer as given below
4. Enable devel_entity_updates
5. Use the drush commands provided by the devel_entity_updates to perform entity updates on payment_receipt as mentioned below
6. Copy the existing data from the cloned table back to the original table using the query written below.
7. Make sure to fill the NULL values with correct values e.g. authorizenet of method column which may have been added before the entity updates
,otherwise it will give error while trying to edit payments section of order or while deleting the payments.

#1 Clone the table

CREATE TABLE uc_payment_receipts_clone LIKE uc_payment_receipts;
INSERT INTO uc_payment_receipts_clone SELECT * FROM uc_payment_receipts;

#2 Clear all values of Method Column.

UPDATE uc_payment_receipts
SET method = NULL

#3,#4 Install & Enable Devel Entity Updates

composer require drupal/devel_entity_updates;
drush pm:enable devel_entity_updates;

#5 Perform entity updates

drush entity-updates

#6 Add the existing data back to the method column from the cloneed table.

UPDATE uc_payment_receipts
INNER  JOIN uc_payment_receipts_clone 
ON uc_payment_receipts.receipt_id = uc_payment_receipts_clone.receipt_id
SET uc_payment_receipts.method   = uc_payment_receipts_clone.method;
kruser’s picture

@hash6 Thanks for this! It worked great. I just wish I found it 3 hours earlier :)