Repro:
On existing site, updated a pre-existing entity (content type = node) with new fields
Created a new feature with only that content type as a component.
Moved newly created feature to a clone of the website but without the change in the content type
Attempted to enable the new feature.
Observed "DatabaseSchemaObjectExistsException" (see attachment)

There should be a way to update the schema, not just create a new one. Or if there is, it doesn't seem to be documented

Comments

henrikakselsen’s picture

Same problem here. I try to avoid changing content types via features as much as possible because of this issue.

PawelR’s picture

I had the same problem.
I added and removed some fields but also changed values in one select field
Next I tried to revert field settings in this feature (which was in 'needs review' state).
As far as I think what happened features started adding new fields (and creating new db tables for them) until it encountered this field with amended list options, it couldn't revet it and raised exception.
Next time when I clicked revert it tried to repeat exactly the same but this time it failed earlier because db tables which Features wanted to add were already there.
First exception was about select field with amended options, next exceptions were about new field I wanted to add. It's quite important to remember name of the field mentioned in first exception.

This is how I managed to fix this:
First I restored db to state before that mess. Machine name of my field with changed select options was field_proposal_status. I performed following db queries directly on the database:
1. DROP TABLE field_data_field_proposal_status;
2. DROP TABLE field_revision_field_proposal_status;
3. DELETE FROM field_config WHERE field_name="field_proposal_status";
4. TRUNCATE cache_field;

After that I reverted this feature without any problems.

If maintainers knows what's going on and could point me in the right direction then I can try to fix that and provide a patch.

rogerrogers’s picture

Just got burned by this too, but in my case the problem was that I'm using the Backup and Migrate module, which can leave extra fields, since it doesn't drop all tables first!!! See: http://drupal.org/node/1104012

So, if you are using BAM, make sure you don't have artifact fields in your DB.

xtfer’s picture

Title: New feature with existing content type fails » New feature with existing tables fails
Version: 7.x-2.0-beta1 » 7.x-2.0-rc2
Assigned: Unassigned » xtfer
Status: Active » Needs review
StatusFileSize
new1.34 KB

I've seen this regularly with features that are altered or refactored after installation. If, for example, a field is moved into a "common fields" module after creation, this error makes it almost impossible to recover, when it's quite likely there is actually no issue.

Because ANY exception thrown by a component could cause this to occur, and thus block loading the Features or Module page even to simply disable the offending module, this patch catches the Exception and logs it, while warning the initiating user that something may have gone wrong. This gives the opportunity to rectify, if necessary.

hefox’s picture

Imo features should not be rebuilding during loading of modules/features page automatically; that seems unnecessary expansive.

xtfer’s picture

Those pages aren't exactly lightweight - and you have to rebuild sometime. In any case, there's a separate issue which provides an option to disable that rebuilding.

hefox’s picture

I'll be clearer -- I dislike the idea of _features_restore blindly capturing any exceptions and would rather make it possible to recover by not doing features rebuild during unexpected times.

I'm quite familiar with the issue mentioned.

xtfer’s picture

It doesn't matter when you do the features rebuild, though, you are still going to strike this problem. Not doing features rebuilds on the pages mentioned is a different problem. This issue is about properly handling Exceptions thrown by Drupal core when rebuilding fields.

We can narrow it down to just that exception type if you like, but it begs the question why we wouldn't want to handle Exceptions thrown during an action? Since there's only one way of performing all these actions through the invoke function, catching them seems like the only possible solution?

hefox’s picture

I believe we're currently handling catching exceptions in the hook_features_rebuild/revert functions -- I think there's an issue that added catching an exception catching for fields recently (is this a duplicate?).

xtfer’s picture

Yes, there was one for fields.. #1664160: Catch field exception when rebuilding This is probably a follow-up.

That issue deals is actually that Fields thrown an exception during the 'features_enable_feature' step, and this step can be run during a rebuild, but I would expect this could happen on any of them. Dealing with it in the rebuild step only addresses one of those issues.

A better way to deal with it may be to centralise field creation into a single handler for all features actions, and catch it in there.

spgd01’s picture

Issue summary: View changes

I am still having this issue. It is killing my websites. Any Updates?

kenorb’s picture

Status: Needs review » Reviewed & tested by the community

For me the patch works, at least it doesn't break completely and continue with feature revert.

kenorb’s picture

vinmassaro’s picture

In my case, I think this happened when a feature was enabled, then disabled and uninstalled, and the fields were left behind. I attempted to enable the feature again and it throws a DatabaseSchemaObjectExistsException. With this patch, it continues and warns me that the revert failed.

hefox’s picture

Version: 7.x-2.0-rc2 » 7.x-2.x-dev
Category: Bug report » Feature request

Features rebuild can cache clear can be disabled via settings.php, which allows for recovery.

Marking this as a feature request but there's been no mention of an actual bug other than outdated databases (e.g. ones that contain tables to fields improperly deleted). I'm hesitant about 'fixing' an issue like that -- should it really support corrupted databases? If there's an actual bug in features that get it to that state, fix that. If that makes sense.

xtfer’s picture

Going to way in again here.

Features rebuild can cache clear can be disabled via settings.php, which allows for recovery.

Right, by recovery I assume you mean, delete the tables and reinstall the feature? That's not a recovery if you'd like to retain the data.

Marking this as a feature request but there's been no mention of an actual bug other than outdated databases (e.g. ones that contain tables to fields improperly deleted).

We use features for production deployments between environments. As @vinmassaro alludes to in #14, this can happen relatively easily when switching branches in git-based development environments.

The database is not corrupt, its in the correct state, the problem is features is trying to recreate something which already exists. It needs to be a bit more intelligent. Blindly assuming that the database must not have the tables doesn't help anyone. Throwing an Exception in this case really helps no-one, especially during a deployment phase.

hefox’s picture

Deleting a field should delete it's tables. Not sure what you are doing that isn't doing that (you might have mentioned above), but going around existing api's is not really expected.

In that situation, generally have a new name for the new field, migrate the data, then delete the old field.

hefox’s picture

Status: Reviewed & tested by the community » Postponed (maintainer needs more info)

Please provide a situation where this issue occurs via normal site development/proper use of apis/etc.

spgd01’s picture

I get this all the time when trouble shooting issues. If I need to disable a specific module thus disable a feature and then re-enable a feature I get the DatabaseSchemaObjectExistsException error.

stewart.adam’s picture

I'm seeing this as well after upgrading a Commerce Kickstart site from an old release (2.9) to the latest one (2.35). field_data_field_product_category was missing from the field info but the tables were in the DB, and since the fix for #2534138: field_base_features_rebuild doesn't catch exceptions. checks only for FieldException but not DatabaseSchemaObjectExistsException clearing the cache which I needed in order to rebuild the field info in the first place, failed.

xtfer’s picture

Yes, partly.

justaman’s picture

Here is a workaround.

Backup tables,
delete tables,
let the feature revert
restore fields data from backup.

Here it is clear there is some control data lost, fields are not only the data and revision tables but something else. The feature is able to fix that something else. Then we bring data back.

field_base_features_rebuild() calls field_info_fields() calls getFields(): the field is not there, the feature tries to create. One should check the field creation or features revert code to find where is it writing the lost control data, and from there fixing this would be just writting that control settings back. Please consider https://www.drupal.org/files/er_db_schema_drupal_7.png .

In my case, I am moving a DB from one branch to another, where the features were refactored. So the old version is too early to uninstall them (as it should keep running), and the new version is too late(as the features are not there anymore). I should not be lazy and create a middle version, but I am in a rush right now.

gisle’s picture

Status: Postponed (maintainer needs more info) » Active

In #18, hefox wrote:

Please provide a situation where this issue occurs via normal site development/proper use of apis/etc.

To reproduce, do the following:

  1. Create a node content type in the GUI, and create a features export module of it.
  2. Install and enable this module on another website.
  3. Disable and uninstall the feature module.
  4. Re-enable the feature module.

This triggers the following DatabaseSchemaObjectExistsException exception:

screenshot

What causes this exception is the following: Features does not generate hook_uninstall() to uninstall the node content type it creates when the features module is uninstalled, leaving behind gunk in the database. When the features export node is re-installed, that gunk triggers the exception.

The obvious workaround is for the developer to create the missing hook_uninstall() “by hand”, and add it to the features export module.

However, Features is billed as a module that automatically creates all the code required to export a node content type from the GUI into code, and many of its users probably do not know how to program. Not generating the necessary code to implement hook_uninstall() is IMHO not only a missing feature, it is a bug (but I shall refrain from changing the category).

IMHO, the patch provided in #4 is not a desirable solution.

kenorb’s picture

Assigned: xtfer » Unassigned
guypaddock’s picture

@gisle's steps in #23 are for a different issue entirely -- that Features doesn't remove structure during feature uninstall. IMO that was #1367240: A clear mental model on how feature components should act on uninstall/disable and its related issues.

See #2856600: Feature revert - Fields are not created but field tables created in MySQL for steps that reproduce exactly the issue that brought me there (and here). I am thinking that these two issues are the same issue, but am not 100% certain so I'm not marking this issue as a dupe for now.

guypaddock’s picture

The patch in comment #87 of issue #1551132 provides a workaround for this issue for me, at least. Still feels like solving the symptom rather than the cause; I would not expect Features to re-create a field that has tables.