Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
Reinstalling modules containing default content results in a database constraint error on the entities' UUID.
I believe this could be avoided with the following patch, resulting in only updating already existing entities, not trying to save them as new ones.
Adding reference to previously mentioned entity revisions issue
Comment | File | Size | Author |
---|---|---|---|
#175 | default_content-fix-uuid-duplicate-entry-2698425.patch | 945 bytes | b.khouy |
#173 | 2698425-173.patch | 3.16 KB | Leksat |
#171 | 2698425-171.patch | 3.21 KB | meanderix |
#170 | 2698425-170.patch | 2.94 KB | meanderix |
Issue fork default_content-2698425
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #2
Karsa CreditAttribution: Karsa commentedFixed incorrect entity key usage in original patch.
Comment #3
plopescRe-rolling patch using the right base to be added using composer.
Also removing call to deprecated
\Drupal::entityManager()
Thanks
Comment #4
mstef CreditAttribution: mstef commentedNot working for me. I'm using this module and exports in an installation profile. All of the nodes I exported are created by the admin (uid 1), so that user is exported as well. If I don't export that user, all nodes are given an anonymous author.
I'm getting:
Comment #5
morsokKinda had the same issue : The patch helped but I had a duplicate on the revision table (block_content_revision).
This patch add a single line that fixes this particular problem, but i'm not sure this is how we want to do it ?
Putting this to needs review but the comment above kinda says need work.
Comment #6
jamedina97 CreditAttribution: jamedina97 commentedI think morsok was right about adding a single file to solve the duplicate on the revision table but some entities does not support revision.
This patch add "try - catch" to get the LogicException in that cases and scape this line when the entity does not support revisions (user or file entity type as example).
Not sure if I'm in the right way, I hope this helps.
This is my first patch, exciting to help drupal community ;-)
Comment #7
pguillard CreditAttribution: pguillard commentedIt seems it works well. I can import my content multiple times now, which is cool, specially to test content recently exported !
Comment #8
yobottehg CreditAttribution: yobottehg commenteddeleted because that was no useful input ...
Comment #9
yobottehg CreditAttribution: yobottehg commentedComment #11
chr.fritschPatch works fine for me. Thanks
Comment #12
pguillard CreditAttribution: pguillard commentedI guess this is RTBC then..
Comment #13
larowlanCan we have a test to go with this please - thanks.
Comment #14
yannisc CreditAttribution: yannisc at Netstudio commented#6 worked for me as well.
Comment #15
yannisc CreditAttribution: yannisc at Netstudio commentedWhile the patch allows to reimport the same content, it doesn't prevent the following error when trying to reimport users:
Drupal\Core\Database\IntegrityConstraintViolationException: [error]
SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry
'0' for key 'PRIMARY': INSERT INTO {users} (uid, uuid, langcode)
VALUES (:db_insert_placeholder_0, :db_insert_placeholder_1,
:db_insert_placeholder_2); Array
(
[:db_insert_placeholder_0] => 0
[:db_insert_placeholder_1] =>
82472cdf-55bb-4514-9fbd-0338bed71547
[:db_insert_placeholder_2] => en
)
in Drupal\Core\Database\Connection->handleQueryException() (line 668
of /core/lib/Drupal/Core/Database/Connection.php).
PDOException: SQLSTATE[23000]: Integrity constraint violation: 1062 [error]
Duplicate entry '0' for key 'PRIMARY' in core/lib/Drupal/Core/Database/Statement.php:59
Comment #16
youfei.sun CreditAttribution: youfei.sun commentedHi, after applying #6, I got the following error on re-enabling the module, I guess it is because 'id' field is not exist for block_content entity.
Okay, id not exist is caused by json files left in the folder without uuid setup in the yml file, I think #6 is working for me now.
Comment #17
keesje CreditAttribution: keesje commentedPatch #6 works for me. tested taxonomy_terms only.
Comment #18
keesje CreditAttribution: keesje commentedProbably duplicate of https://www.drupal.org/node/2640734, #7 patch has "update" feature too
Comment #19
ao2 CreditAttribution: ao2 as a volunteer commentedHi,
I am seeing the same issue as mstef from comment #4, either with or without patch from #6 applied.
I too have content with
admin
as author.I am exporting the content in this way:
So the
admin
user is also exported incontent/user
, as it's referenced in the content.When I install the profile which provides the previously exported content I get the error, apparently the code tries to re-add the
admin
user?It would be great to sort this out, providing default content written by the admin user may be convenient when setting up a demo site.
I also tried the patch from #2640734-22: Allow manual imports which does something similar, but it does not solve the problem either.
Thanks,
Antonio
Comment #20
vijaycs85Looks like #2640734: Allow manual imports has all the changes we have here. We can either
a) Add tests for this change and commit this issue and make #2640734: Allow manual imports blocked until this issue get in.
b) Close this issue (and give credit people worked here on #2640734: Allow manual imports ) as duplicate
either way, we need tests...
Comment #21
andypostThis issue is about to allow imports again so it have nothing common with #2640734: Allow manual imports
Comment #22
kalpaitch CreditAttribution: kalpaitch as a volunteer and commentedTaken all the work and comments from #2640734: Allow manual imports and rolled them into this patch.
I will leave someone else to decide if tests for import functionality should be part of this ticket or another.
Comment #24
robert-os CreditAttribution: robert-os at One Shoe commentedBased on #6, but made sure the entity id is set to NULL. This is basically what Entity::createDuplicate() does , but we want the uuid to stay. https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Entity%21...
Comment #25
kalpaitch CreditAttribution: kalpaitch as a volunteer and commentedPatch #22 failed because of Dependency to rest module
This patch takes into account the issues with manual import as described in https://www.drupal.org/node/2640734#comment-11862933 && https://www.drupal.org/node/2640734#comment-11900803 just setting this back to the default patch to work from once the rest dependency issue is fixed in tests.
Comment #27
andypostI commited #2848425: Dependency to rest module so tests no longer break, but this still needs a basic test
Comment #29
kalpaitch CreditAttribution: kalpaitch as a volunteer and commentedSeems sensible.
Comment #30
kalpaitch CreditAttribution: kalpaitch as a volunteer and commentedAdded additional functional tests, as per the current import tests, to check re-importing of content.
Comment #31
vijaycs85Looks good to me. Let's wait for the tests to finish...
Comment #32
chr.fritschI have tested the latest patch with our thunder demo module and it works as expected
Comment #33
getu-lar CreditAttribution: getu-lar as a volunteer commentedAlso reviewed and tested. Works as designed.
Comment #34
larowlan+1 RTBC but we'd like to get #2614644: Split DefaultContentManager into Exporter and Importer in first
Comment #35
larowlanComment #36
diegodalr3 CreditAttribution: diegodalr3 at Skilld commentedRemove diff in
tests/modules/default_content_test/default_content_test.info.yml
because causes errors when using make file.Comment #37
robert-os CreditAttribution: robert-os at iO commentedStill had problems with duplicate id's, so made sure the entity id and revision id are set to NULL when it's a new entity.
Comment #38
kalpaitch CreditAttribution: kalpaitch as a volunteer and commentedInterdiffs plzzz!!! Make it easier... Anyhow, we gotta wait for #2614644: Split DefaultContentManager into DefaultContentExporter and DefaultContentImporter
Comment #39
andypostNeeds update because #2614644: Split DefaultContentManager into Exporter and Importer
Comment #40
Berdirabout the problem with uid 1, what you need to do is calling ->accessCheck(FALSE) on the entity query.
Comment #41
kalpaitch CreditAttribution: kalpaitch as a volunteer and commentedAh cool awesome @berdir. That's useful if writing own entity query. So now to decide whether to write own entity query or to use account switcher??
Comment #42
kalpaitch CreditAttribution: kalpaitch as a volunteer and commentedRe-rolled.
Incorporating #37 makes #2689069: Do not import entity IDs (included in exports from Drupal 8.1.x) a duplicate of this ticket.
@berdir would you suggest writing a custom query for the uuid lookup?
Comment #43
kalpaitch CreditAttribution: kalpaitch as a volunteer and commentedComment #45
kalpaitch CreditAttribution: kalpaitch as a volunteer and commentedComment #46
kalpaitch CreditAttribution: kalpaitch as a volunteer and commentedComment #47
andypostI'd like to get @Berdir eyes on the rest
While we enable updates then event should allow subscribers to separate updated and created entities
So I see 2 ways
- 2 events (updated & created)
- one event and a way to separate updated/created
Also we can store result of save into event
Mostly nits
Save also a question, because some properties receive default values (node author)
I'd better keep this protected
Comment #48
dawehnerIs there an existing core issue about it / does anyone mind open up a core issue about that? This API functions should NOT respect access checking, IMHO
Comment #49
kalpaitch CreditAttribution: kalpaitch as a volunteer and commentedSure, so as @berdir mentioned it would be perfectly possible to look up uuid with a custom query that does NOT respect access checking (which may be better) but using the existing entity repository service it looks like the entity uuid lookup does not have a skip access permission flag.
Comment #50
andypostThat's sounds like needs core issue
Comment #51
andypostbtw it makes sense to coordinate in #2691085: Schedule alpha 9 release
Comment #52
Yaron Tal CreditAttribution: Yaron Tal at One Shoe commentedReroll of the patch in #45 against the latest dev version which already has nitpick 1 from #47 in it, and I fixed nitpick 2.
Also I created an extra event as also suggested in #45. This way the existing event stays the same (only imports), so existing integrations will keep working exactly the same.
Comment #53
Yaron Tal CreditAttribution: Yaron Tal at One Shoe commentedComment #54
andypostHere's a bit of clean-up + todo
I'm sure we need to resolve that here somehow
FYI Solving import of existing contend is blocker for all import issues like #2640734: Allow manual imports
Comment #55
andyposta bit more clean-up
btw What if entity with parsed ID exist? the whole import will fail but should not, imo.
Comment #56
kalpaitch CreditAttribution: kalpaitch as a volunteer and commented@andypost #48 was addressing the issue of entity with parsed ID existing. Patch #52 removed this ability to lookup the existing entity correctly without adding an alternative. Suggest we either add #48 back in, add a core patch or add our own entity lookup which bypasses access checks.
Comment #57
andypostI think
lookupEntity()
better to isolate in ptotected method at least, I needs to dig it deeperAnd I also sure that we need core issue about loading with skip entity access
As hotfix we can use entity query to skip access check and if entity found load it
Comment #58
r.nabiullin CreditAttribution: r.nabiullin at Skilld commentedPossibly as temporary solution.
I removed, from patch #55, the assignment of NULL to id and revision of the entity, because for some entities import with ID is a necessary . Import and update work is correctly for me.
Comment #59
kalpaitch CreditAttribution: kalpaitch as a volunteer and commentedCool @andypost.
@nabiyllin I don't think this is correct, IDs and revisions should not be imported, that's what the uuid is for. Can you describe your use case?
Comment #60
andypostWe still need IDs because there still parts that reference by them, see #2304849: Stop excluding local ID and revision fields from HAL output
+ that required to detect uid 0 & 1 to assign them properly to local ones
Also I think about collision with #2640734: Allow manual imports
Comment #61
kalpaitch CreditAttribution: kalpaitch as a volunteer and commentedOk, but that is an exception rather than the rule I feel. Trouble is we now need figure out which is the actual reference id. As in should we lookup whether the entity id exists and update that, or should we lookup whether the entity uuid exists and update that, or both, but what if the uuid exists for a different id?
Let's say we're importing nodes:
Into an existing site:
My feeling is that for certain drupalisms, like uid 0 & 1 which have other meanings then we have 'exceptions' and can lookup the id instead of the uuid and/or provide an event for this.
Comment #62
andypostthat's main pita here, mostly everywhere reference made by UUID except few places
That's exactly a lookup that I'd prefer to delegate to other class method
Comment #63
kalpaitch CreditAttribution: kalpaitch as a volunteer and commentedCool, yea definitely worth delegating. Will have a play later.
Comment #64
kalpaitch CreditAttribution: kalpaitch as a volunteer and commentedIntroducing an entityLookup method. This abstracts just enough and also takes care of the access check issues, although I notice in the master branch the whole import is running as root user anyway??
@nabiyllin @andypost Considering the root user anomaly I still believe we would never import a new ID. We may update an entity and use that ID, but the IDs that come through from the json input should not be used as they are unreliable across sites. Take the following example:
Json Import
New Site
In this example, when we import we would want:
User 1 in the json to inherit the uuid of User 1 in the new site, this avoids any collisions with User 2 in the new site which has the same uuid (we may even want to automatically detect these collisions and remove User 2 in the new site??
User 2 in the json to inherit the uuid from User 3 in the new site (but we would not want to remove user 2 in the new site).
User 3 in the json to be created in the new site as User 4.
We do not want:
User 3 in the json to become User 3 in the new site.
Comment #65
r.nabiullin CreditAttribution: r.nabiullin at Skilld commentedWhen you import new taxonomies with parents, you should, as least, import parent taxonomy with ID from json, because in daughter taxonomy in links and embedded parts filled parent id which is used to build a hierarchy.
Comment #66
larowlanAre you using this for default content or content staging? We're interested in a modules/profiles providing default content at install time, not in perpetuity.
I have no interest in making this module aware of all the nuances required for content staging. Use another module for that.
If you're using it for default content - in what instance would you get uuid collisions/issues other than for user 1 and 0?
I don't understand the use-case that can lead to the issues you're listing.
Comment #67
andypost@larowlan my main case here is predictable error handling & basic colision detection for #2640734: Allow manual imports
If module has default content there no way to install it again. #2842749: A single failure during module install prevents any further content processing
Secondly #2803005: Add helper function to allow individual content import (useful in update hooks)
And finally #2849128: Add handling of ConfigEvent::IMPORT_MISSING_CONTENT
Btw that's looks like a part of content staging because it's) We stage predefined content for install time) and it leads us to related issue again
Comment #68
kalpaitch CreditAttribution: kalpaitch as a volunteer and commentedAnd predictable collision detection when enabling the module on a site with existing content.
IMO in all cases, except user 1, this can be achieved by looking up the uuid and ignoring internal IDs.
In regards to the taxonomy terms case I think content items maintaing references to each other by internal site IDs is a problem with the normalisation of the content item.
Internal site IDs are only relevant on the site on which they were generated.
Comment #69
larowlanOk, gotcha - thanks for the explanation
Comment #70
kalpaitch CreditAttribution: kalpaitch as a volunteer and commented@dawehner opened up #2878483: loadEntityByUuid() should skip access checks in relation to #48.
@nabiyllin With taxonomy terms I can see what you mean by the _links still referring to internal IDs:
However the actual reference is still done by uuid, I'd be interested to hear what the self link is used for in this module. I've done a test importing a parent and child term into a site which already has taxonomy terms IDs 1 & 2 registered and it's maintained the correct parent-child relationship but inserted as new so I don't think this is an issue.
I think that's everything listed in the comments, this seems to avoid all the collisions I've detected in my testing.
Comment #71
ao2 CreditAttribution: ao2 as a volunteer commentedIf the main use case of default_content is to import content assuming that no different/unrelated content is already in the database, it may be worth improving the delete_all module (see #2857363: Add the --reset option to the D8 branch) and propose it as a companion module.
Comment #72
saramato CreditAttribution: saramato at RatioWeb commentedAfter applying patch: https://www.drupal.org/files/issues/default_content_do_not_reimport-2698...
error appears
Listing here: ttps://www.drupal.org/files/issues/default_content_do_not_reimport-2698425-64.txt
Occurs, during enabled/disabled "my_custom_default_content" module
Before applying patch I had:
Uncaught PHP Exception Drupal\\Core\\Entity\\EntityStorageException: "SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '9' for key 'PRIMARY': INSERT INTO {block_content} (id, revision_id, type, uuid, langcode) ....
Comment #73
lammensj CreditAttribution: lammensj at iO commentedMinor adjustment: the Importer has a default value for the $update_existing parameter (FALSE) in the importContent-function. The interface does not. The patch included fixes this.
Comment #74
kalpaitch CreditAttribution: kalpaitch as a volunteer and commentedThe interface is a contract, it shouldn't define values for these properties IMO.
Are you happy with the rest of this patch @LammensJ ?? Would be good to focus on getting this reviewed and tested.
Comment #75
eelkeblokI tend to agree with LammensJ. The interface is a contract, yes, but default values for parameters have a direct bearing on how the method is called and whether a value can be left out when calling the method or not. If the default value is left to the implementation, the caller will need to care about what implementation is used in order to know whether they can leave out the parameter, which is contrary to the point of having an interface in the first place.
I would have liked to do a complete review, but unfortunately that'll have to wait until next week, maybe. Unless somebody else beats me to the punch, of course :)
Comment #76
eelkeblokIs there a reason this patch does not actually enable the use of the $update_existing flag? (Maybe it's been mentioned and I missed it).
Apart from that, just some nits:
Variable name in the docblock is incorrect, should be $entity_type.
Shouldn't we be checking if there is anything in the $created and $updated arrays before sending the event? Or is there any value in sending an event notifying that there was nothing updated or deleted?
The return value needs a description and the arguments need type hints (according to php_cs).
Comment #77
kalpaitch CreditAttribution: kalpaitch as a volunteer and commented1, 2 & 3 all fair points.
The reason for not including $update_existing flag is that at the time #2640734: Allow manual imports hadn't been completed. It can be added now.
Comment #78
timmillwoodWe're currently facing an issue with Multiversion module plus Default Content module. Multiversion has an entity type Workspace, and all content is linked to a workspace via an entity reference. Default content tries to export/import these workspace entities, but Multiversion also creates the default one on install.
I am hitting issues similar to #4. The latest patch fixes the issue, but then install (via drush si) never completes.
Comment #79
nedjoWorking on a related patch in Better Normalizers: #2913001: Add option to exclude local ID and revision ID values. Rather than ignoring on import, this would remove local ID values on export.
Comment #80
timmillwoodFixing nits in #76.
Comment #82
timmillwoodSorry, that was completely the wrong patches in #80.
Comment #83
robpowellHas anyone got #82 to work? I tried installed through composer-patches but it failed.
Comment #84
kalpaitch CreditAttribution: kalpaitch as a volunteer and commentedWorks like a charm. Let's get this in...
Comment #85
larowlanComment #86
nedjoThis is generally looking good. Here's a review noting a few outstanding issues.
The comment says "Never", but the code will not be executed in the case that
$update_existing
isTRUE
and there is no$old_entity
.Since not all content entity types are revisionable, we should test (using the
::isRevisionableEntity()
method introduced in this patch) before setting this property.This line is hard to follow and could use a code comment.
The naming here is inconsistent. The method is
::importContent()
. In the update case, we test for a variable$updated
and, appropriately, dispatch anUPDATE
event. But in the create case, we test for$created
but then dispatch anIMPORT
event. The expected event constant would beCREATE
.This description (and the method name) implies a boolean return value, but what we're actually doing is loading or getting the entity (if it exists).
The fallback return value is an empty array.
Indentation issue.
Indentation issue.
Comment #87
Manuel Garcia CreditAttribution: Manuel Garcia as a volunteer and at Appnovation for Pfizer, Inc. commentedThis is breaking the import of new entities with references to each other, since the exported entity id is being used for the reference, and this part triggers a new entity id to be generated. At least this is as far as we've been able to investigate.
Comment #88
andypostI'm sure revision support needs review
I see 2 cases here
1) embed - mostly users, 0 & 1 both needs mapping, others need own conflict resolution
2) relations - block_content, menu items, terms, files all needs selector at revision uuid change & they may have other revisionable dependencies
Comment #89
andypostAh... and how to deal with translation revisions?
Comment #90
andreyks CreditAttribution: andreyks at Adyax commentedThis lines break import entiies where entity_key "id" is not serial but is string. For example entity_subqueue:
entity_keys = {
Will add fix soon
Comment #91
andreyks CreditAttribution: andreyks at Adyax commentedComment #92
Manuel Garcia CreditAttribution: Manuel Garcia as a volunteer and at Appnovation for Pfizer, Inc. commentedThanks @andreyks - I like where #91 is going. Looks to be addressing #87 too. Setting it to needs review for the tests to run.
Comment #93
Manuel Garcia CreditAttribution: Manuel Garcia as a volunteer and at Appnovation for Pfizer, Inc. commentedNits: indentation is off.
Comment #95
andreyks CreditAttribution: andreyks at Adyax commentedcoding standards fixes only
Comment #96
andreyks CreditAttribution: andreyks at Adyax commentedComment #97
Manuel Garcia CreditAttribution: Manuel Garcia as a volunteer and at Appnovation for Pfizer, Inc. commentedJust a comments review
them -> they
Check if imported -> Check if an imported
The entity type of the entity that will be imported?
If so, let's say so instead :)
Comment #98
andreyks CreditAttribution: andreyks at Adyax commentedTODO: handle error if current item already exists and $entity_type->getKey('id') is required and is not auto incremented
Comment #99
andreyks CreditAttribution: andreyks at Adyax commentedComment #100
SocialNicheGuru CreditAttribution: SocialNicheGuru commentedI edited the title. I had this issue: Taxonomy terms causes duplicate entity errors - possible solution integrate with taxonmy_machine_name
This patch solved it.
See the other issue for the error.
I don't know if you disable the module with default terms and then re-enable it. Will the terms be re-imported again?
Comment #101
das-peter CreditAttribution: das-peter at Cando commentedResetting the revision id or enforcing a new revision seems to break EntityReferenceRevisionsItems. This reference type references a specific revision of an entity. The serialized data maintains the revision ids.
So if we reset the revision id to avoid collisions we'd need to update all field contents with EntityReferenceRevisionsItems as well.
Comment #102
das-peter CreditAttribution: das-peter at Cando commentedI've tried to tackle the issue I've reported above but the solution doesn't feel very clean.
If someone has a an idea how to solve that in a nicer way please let me know :)
Comment #103
eelkeblok@SocialNicheGuru: Please excuse my bluntness in renaming the issue back, but I feel "renumbering" entries is an implementation detail and has no business in the issue title; new content should just get the next numeric ID, whether it is the result of an import or a regular, manual content entry. In general, I would say this module should not be concerned with local IDs; what uniquely identifies a content item (and should determine what is "existing" in terms of this issue) is the UUID. The actual numeric database ID is an implementation detail (and since we are exporting it, and using the exported value when creating the content (?), maybe we should indeed get rid of that completely, as suggested in #79).
Or, maybe I am missing something, in which case, please explain in more detail why you feel the title change is warranted.
@das-peter: Do you have an interdiff (i.e. a "patch" between your version and the last contributed patch)? That makes reviewing your changes easier.
@#104: Huh.. Not sure how I missed it. Sorry about that.Comment #104
das-peter CreditAttribution: das-peter at Cando commented@eelkeblok: Interdiff is already in #102 - see the file "interdiff-2698425-99-102-do-not-test.diff"
Comment #105
eelkeblokRight.. Sorry about that, not sure how I missed it. One quick remark. A way to maybe unfold the "rat's nest" of ifs and foreaches might be to reverse some of the ifs and do a
continue
to move onto the next item. This allows the "happy flow" to move a level up.Comment #106
robpowellTwo nitpicks
Can type hint these two parameters
Can type hint these two parameters.
Comment #107
kalpaitch CreditAttribution: kalpaitch as a volunteer and commentedI don't know whether this has been mentioned (so many comments) but `existEntityId` isn't working as expected. See below:
The first count comes out as 0 whereas the second comes out as 1. Whether this is a product of some kinda weirdness in my use case I cannot tell yet but there seems to be an issue with the matching query.
EDIT: Scrub that it is a bit of database corruption :)
Comment #108
neclimdulI'm not sure how this is connected and it is going to be super brittle in all those cases were content does already exists. The array will often not be populated because no content is being created or updated.
I think if we fixed the fact revisions can go haywire during import maybe that's less an issue though. This issue is specifically about dealing with entity reference revisions and could easily be merged in I wager.
https://www.drupal.org/project/default_content/issues/2989887#comment-12...
Comment #109
RumyanaRuseva CreditAttribution: RumyanaRuseva at FFW commentedAdded missing type hints and removed unused variables.
Fixed existEntityId() not to fail for empty entity id. Related to #2969631: NID / VID / TID conflicts in branches though I see that the tests failed with the same error.
Comment #110
agentrickardThe patch just allowed a clean import for me. Nice work.
Comment #111
larowlanwhitespace errors here
this looks like the patch contains a patch file too?
Confirmed locally:
does it? Or is it an UpdateEvent?
Sorry, I don't want to introduce this. Instanceof is a code smell, and it is very much out of scope here.
This is about reimporting existing entities, not adding support for ERR. A separate issue for that is where it should go, and with tests. Combining the two means the patch is far less commit-able.
I don't like this knowledge being handled here, I'd much prefer a conflict resolution system like entity pilot module has, so it is pluggable. However, perhaps it would look nicer without the out of scope ERR changes.
we're repeating this logic, it feels like this hunk could be refactored
we're returning an empty array, not null?
I don't want to special case this. Again, a pluggable system like entity pilot has would be more elegant
do we need to pass the entity type if we have the entity?
when would this ever be more than one value?
Comment #112
BerdirAgreed that this is not nice, however I assume the reason for having it here would break existing default content that right now does not require anything special for ERR.
Comment #113
itamair CreditAttribution: itamair commentedhi folks, for sake of completeness ... this issue #109 patch is corrected (not to wrongly include the default_content-dont-reimport-existing-entities-2698425-102.patch file) and embedded (and extended) into this related one: Allow updating existing content (and don't reimport existing), that stably applies to the 8.x-1.0-alpha7 branch
Comment #114
fabiansierra5191 CreditAttribution: fabiansierra5191 as a volunteer commentedLooks like the patch #109 still has some issues. I created a module and when the site has no content worked prefect but when I had some content I got this at the moment to enabled it:
Error: Maximum function nesting level of '512' reached, aborting! in Drupal\Core\Extension\ModuleHandler->getImplementationInfo() (line 577 of /app/webroot/core/lib/Drupal/Core/Extension/ModuleHandler.php).
Comment #115
e0ipsoI didn't change the functionality of this, but I addressed most (all?) of the feedback in #111. I also changed a bit the patch structure to improve (hopefully) readability a bit.
I put the ERR in a private method so it can be removed easily if needed after @larowlan addresses @Berdir's comment on #112.
Comment #116
matthieuscarset CreditAttribution: matthieuscarset as a volunteer and commentedUsing either #109 or #155 patches, I have a scenario which still raises an exception when trying to import existing Users:
How to reproduce
drush si minimal
)drush user-create --mail=yourmail@gmail.com
)drush dcer node --folder=modules/custom/<module>/content -y
)drush si config_installer -y
)=> Exception:
SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '0' for key 'PRIMARY'
Workaround
Either
UID: 0
)Comment #117
BR0kENWhy do we pollute RAM by collecting
$updated
?Why return a list of created content is needed? I'd stop collecting
$created
and make the method return nothing.The
array
type hint is missing.-
private
makes it impossible to even reuse the method. I prefer to inherit from the original service and this makes impossible to use its functionalities fully. I'd make itfinal
instead.- The
array
type is missing for$revision_links
param.Comment #118
jts86 CreditAttribution: jts86 at IBM commentedValidate ERR exists before fixing targets.
Comment #119
jts86 CreditAttribution: jts86 at IBM commentedAvoid unnecessarily asking for ERR on every iteration.
Comment #120
jts86 CreditAttribution: jts86 at IBM commentedRerolling previous patches (118 & 119) as there was an issue applying them.
Comment #121
das-peter CreditAttribution: das-peter at Cando commentedIf I'm not mistaken this won't ever resolve to true.
Either we use the full namespace
\Drupal\entity_reference_revisions\EntityReferenceRevisionsFieldItemList
or we change it touse Drupal\entity_reference_revisions\EntityReferenceRevisionsFieldItemList
and then check withif (!$field instanceof EntityReferenceRevisionsFieldItemList) {
Comment #122
das-peter CreditAttribution: das-peter at Cando commentedI think the
use
approach is out of question because this relies on a module namespace which might not be available.So I changed the patch to use the full namespace path in the comparison.
Comment #123
ivnish CreditAttribution: ivnish commentedIt implements in the https://www.drupal.org/project/default_content_deploy module
Comment #124
eelkeblok@das-peter are we sure about that? IIRC use statements are besically just aliasing the full name space. It would only cause problems if the code tried to actually instantiate an object for the class that does not actually exist.
Comment #125
xxronis CreditAttribution: xxronis commentedHi all, I used the --122.patch applied to 1.0-alpha8 to install a new module that contains default content that is already in place from another module.
This happens due to topology changes and distributing content in more modules.
Importing configuration with that module enabled produces the
error.
I do not have the file_entity module enabled for any instance @larowlan, as I saw in other issues you mention it can be related.
Any piece of advice is more than welcome, thank you
Comment #126
BerdirI've recently created the 2.0.x branch, see the project page on all the improvements in the 2.0.x branch. Testing that and providing feedback would be very welcome. The 1.x branch isn't actively maintained and won't receive new features anymore.
This specific issue isn't resolved yet, but this also seems to do a lot of changes and seemingly unrelated changes like ERR related improvements. 2.0.x supports ERR composite entities like paragraphs out of the box in the same file/normalization structure, so possibly this can be simplified a lot.
The patch is quite hard to review as it is changing huge parts of code. an updated issue summary that explains what it does exactly would be usefu.
Comment #127
davidferlay CreditAttribution: davidferlay at Skilld commentedTested with patch #122 and 2.0.x-dev
Result : imports fails because it tries to re-create some content with some unique attributes already existing (uuid, id)
Comment #128
scotthorn CreditAttribution: scotthorn commentedA patch on this closed, duplicate issue was made for the 2.x branch. It successfully applies to my build and fixes the error I was seeing on import.
https://www.drupal.org/files/issues/2020-08-03/default_content-integrity...
https://www.drupal.org/project/default_content/issues/3162987
Comment #129
Phil Wolstenholme CreditAttribution: Phil Wolstenholme commentedHere's the patch from issue 3162987 (not my work!) attached to make it easier to test and so we can update the status to 'needs review'.
The patch was contributed by dcraig91.
Comment #130
scotthorn CreditAttribution: scotthorn commentedRemoved the .txt appended to the patch filename.
Comment #131
Phil Wolstenholme CreditAttribution: Phil Wolstenholme commentedUgh sorry, I think Chrome added the .txt when I downloaded the patch file from the closed issue. Thanks for spotting that @scotthorn!
Comment #132
c_archer CreditAttribution: c_archer as a volunteer and commentedPatch in comment #130 worked for me great.
Comment #133
shadcn CreditAttribution: shadcn at Chapter Three commentedAny plans to backport this to 1.x?
Adding a patch for the
8.x-1.x
since this is still an issue in 1.x.Thank you.
Comment #134
Danny EnglanderI ran into this issue as well. I tested the patch in #130 and it worked great. Thank you
Comment #135
johnchqueIt would be nice to have a better comment here. Like "Load the entity by UUID and check if it exists."
Extra white line.
Comment #136
nikitagupta CreditAttribution: nikitagupta at Srijan | A Material+ Company for Drupal India Association commentedComment #137
Eduardo Morales AlbertiAdded drush command to reimport entities.
Comment #139
Danny EnglanderI tested the patch from #137 and it did not apply to the latest dev. #136 applies fine.
Comment #140
jweowu CreditAttribution: jweowu at Catalyst IT commentedI've tested #137 in a Drupal 9.1.4 project with default content for taxonomy terms, nodes, and menu links, and was able to import new content (nodes and menu links) successfully. Much appreciated.
I used an update hook to run the re-import automatically:
For future content additions, just incrementing the update hook number should be sufficient.
Comment #141
Kris77 CreditAttribution: Kris77 commentedI have apply #137 in 2.0.0-alpha1 without problem.
Thanks @Eduardo Morales Alberti
Comment #142
Marios Anagnostopoulos CreditAttribution: Marios Anagnostopoulos as a volunteer and commented#137 also worked for me. The command to import module's contents is also a needed addition.
Thanks!
Comment #143
Marios Anagnostopoulos CreditAttribution: Marios Anagnostopoulos commentedWill be changing it to rtbc if noone has any objections.
Comment #144
Marios Anagnostopoulos CreditAttribution: Marios Anagnostopoulos commentedComment #145
lhridley CreditAttribution: lhridley as a volunteer and commentedConfirming that patch in #136 applied against Drupal version 9.2-dev worked for me when using the update routine in #140 in a hook_deploy_NAME() function (content updates were dependent on configuration executing in a hook_deploy_NAME() function was necessary for content to import properly).
Patch in #137 did not apply; have not tried MR patch from #138.
+1 for RTBC.
Comment #146
kazuko.murata CreditAttribution: kazuko.murata as a volunteer commentedFor entities with translation, #137 doesn't work for me.
An error occurred when saving the entity, when importing a yml with translations like the following for a multilingual site like Umami demo.
For entities without translations, #137 works for me.
Comment #147
Marios Anagnostopoulos CreditAttribution: Marios Anagnostopoulos commentedI have had no issue importing multilingual content. Can you ensure that Spanish is enabled and that the field you are trying to translate are indeed translatable?
Comment #148
kazuko.murata CreditAttribution: kazuko.murata as a volunteer commented@Marios Anagnostopoulos
Thanks for the comment.
I'm trying it out with the page conten type of the Umami demo.
In ContentEntityNormalizer::denormalize(), when $data['translations'] exists
I think I'm getting an error similar to the following
Comment #149
jweowu CreditAttribution: jweowu at Catalyst IT commentedI see that
addTranslation
purposefully throws InvalidArgumentException if a translation for the specified language already exists:Comment #150
Marios Anagnostopoulos CreditAttribution: Marios Anagnostopoulos commentedMaybe you can check this issue here: https://www.drupal.org/project/default_content/issues/3176839.
Let us know if it worked well.
Comment #151
kazuko.murata CreditAttribution: kazuko.murata as a volunteer commented@jweowu
Thanks for checking the code. I understand.
@Marios Anagnostopoulos
Thanks for letting me know #3176839.
It works as expected. The #137 patch is no problem for me.
I appreciate your help.
Comment #152
dxvargas CreditAttribution: dxvargas commentedI'm changing the title of the issue because the old title is deceitful.
With the given patch that is RTBC, existing entities will be updated when importing. So, "Do not reimport existing entities" is incorrect.
Comment #153
lhridley CreditAttribution: lhridley as a volunteer and commentedChanging this back to Needs Work.
After applying the patch (merge diff) from 145, as well as the patch from 150, the default_content module is not handling file entities (from the file_managed table). All file entities are getting imported as new content, even though an entry in the file_managed table with the appropriate UUID is present, and there has been no changes to the image file or the yml content for the exported file entities.
Because of this, when you export changed entities, you get all of the file entities exported with updated image file names, where the original image name was numerically incremented to prevent a file name collision in Drupal when the images were reimported.
Comment #154
lhridley CreditAttribution: lhridley as a volunteer and commentedUpdate: There is another issue in the issue queue in RBTC status, #3200212: Import doesn't overwrite files, that is addressing the issue with overwriting vs. updating files on import. That patch may unblock this issue from "Needs Work" to "RBTC".
Comment #155
lhridley CreditAttribution: lhridley as a volunteer and at FRUITION commentedUpdate: patch from #145 above was applied on an existing site when originally tested.
Adding patch to new site under development, and then attempting to enable a module results in a stack dump:
Comment #156
eelkeblokThere are both patches and a merge request for this issue, I think it makes sense to only use the merge request going forward (note that it is perfectly possible to create alternative merge requests for the same issue). I've hidden the attached files (including a screenshot, but I think that is only relevant to one particular comment - where it is actually embedded - and the file is not gone, it just doesn't appear in the list of attachments for the issue).
Maybe I'm misremembering, but I think the patch behaved differently in the past, and would simply ignore existing content. I personally feel that is much safer, so I wonder whether this is actually something that needs to be controllable with an option, somehow (i.e. default behaviour is non-destructive, if overwrite is desired, an option needs to be passed). For the default installation action, I think it is not a great idea to have content overwritten by default. Disabling and re-enabling a module would become a potentially destructive action. Maybe a warning is appropriate, such as "the module contains content X, but that already exists. If you want to overwrite it, use drush command Y with the Z option".
Comment #157
saitanay CreditAttribution: saitanay as a volunteer and at Globant commentedRTBC +1. The patched code from this issue branch worked great in updating existing content.
Comment #158
mikemadison CreditAttribution: mikemadison at Acquia commented+1 from the open merge request https://git.drupalcode.org/project/default_content/-/merge_requests/5
Comment #159
SiegristI agree with eelkeblok that the module default content should only import content once and ignore them if they were changed. An option to override would also be nice.
The MR doesn't work for me currently. Just did the D9 upgrade. Will debug tomorrow further.
Comment #160
SiegristI have my default content serialized as json. For some reason the
Drupal\default_content\Normalizer\ContentEntityNormalizer
doesn't run, but theDrupal\hal\Normalizer\ContentEntityNormalizer
does. Any idea why this is? I tried to add the normalizer tag to the service with a priority of 11, but the hal service was still prefered.Obviously if the default_content normalizer is not used, we have no impact on checking if the entity exists.
I wonder if the normalizer is the right place to check the existence?
Also I saw if the entity exists further processing is skipped, which is great. (regarding prior comment.)
Comment #161
Berdirdefault_content 8.x-1.x only supports hal_json, it won't use anything else.
default_content 8.x-1.x is also basically unsupported and 2.0.x uses a custom serialization format that does not use the serialization API at all and I strongly suggest to update to that.
Comment #164
bircherHi
Long issue, I have to admit to not reading all the comments but the last few.
I agree that the safer option is to not override existing entities.
I created a new MR because the 2.0.x branch of the other one was confusing to work with. It does, however, contain the commit.
Comment #165
bircherI just realized that there are other issues about the drush command, (#2640734: Allow manual imports) So I am removing that in order for the patches to conflict less.
Comment #166
Leksat CreditAttribution: Leksat at Amazee Labs commentedThanks @bircher! The code looks good. I tested the patch on a project with paragraphs. The PDOException is gone. Paragraphs are imported now without any issues 🎉
I'd vote for merging the MR and creating a release 🙏
Comment #167
Leksat CreditAttribution: Leksat at Amazee Labs commentedAttaching a snapshot of MR#14 (for easy and safe patching)
Comment #168
Leksat CreditAttribution: Leksat at Amazee Labs commentedI have found few other issues with paragraphs. Attaching a patch which fixes them.
Patch summary:
- do not reimport already created entities (by @bircher)
- merge all dependencies (previously it was taking only the root dependencies, so
ContentEntityNormalizer::loadEntityDependency()
was always returningNULL
for sub-dependencies)- paragraphs are exported as entity references (old exported content can still be imported without an issue, but the exported files will change on re-export)
Comment #169
monya CreditAttribution: monya as a volunteer and commentedThanks, @Leksat! Tested, works well on nodes with paragraphs, media, files entities, and layout builder blocks.
Comment #170
meanderix CreditAttribution: meanderix commentedI think we need to use
$entity_type->getKey('uuid')
on this line:Attaching an updated patch.
Comment #171
meanderix CreditAttribution: meanderix commentedAdditional fix: we also need the entity key in the values array.
Comment #172
Martijn de Wit@meanderix, the merge request seems the last step. Can you collaborate in that?
Also change issue status to trigger auto tests
Comment #173
Leksat CreditAttribution: Leksat at Amazee Labs commentedOne more addition. I moved the "existing" check to the upper level. So that the
denormalize
method does only the denormalization.Comment #175
b.khouyWhy not just check in the denormalizer level for entity existence before create it, and whenever an entity with the given uuid already exist then just delete it before recreating the new entity.
Comment #176
sgurlt CreditAttribution: sgurlt as a volunteer and commented#175 works perfectly for me. :-)
Comment #177
NicolasH CreditAttribution: NicolasH commented#175 works nicely for me as well. The approach is a lot simpler than some of the ones above, so not sure if there's any implications I'm missing.
Comment #178
pfrenssenThe patch from #175 is a different approach that will delete the existing content and replace it with the default content. While this might have some use cases this is risky because the existing content might have been updated by an editor, and then the content will unexpectedly revert to the old version if a site builder reinstalls the module that provides the default content.
I think we should stay on the safe side and not mess with existing content, so the approach from #173 is the one we should follow.
Comment #179
pfrenssenIn #2640734: Allow manual imports an
$update_existing
flag was proposed to make it possible to decide whether to ignore existing entities or force to overwriting existing content. This could be useful here since adding this flag could satisfy both the supporters of patch #173 and of patch #175.Comment #180
pfrenssenComment #181
pfrenssenThis still needs test coverage. We can use the tests from #2640734: Allow manual imports as inspiration.
Comment #182
pfrenssenProvided tests. Ready for review.
Comment #183
eelkeblokI did a quick functional test of the latest version of the MR and went through the code changes. Looks great, one question about what happens when $update_existing is true. Would hesitate to put as RTBC until some more people looked at it, especially someone with a keener eye for tests.
Comment #184
eelkeblokPutting on needs work for the feedback.
Comment #187
eelkeblokThanks for all the work everyone. While trying to get a project moved over to default content 2.x and tinkering around with this issue as well as #2640734: Allow manual imports, I found that the code for this issue basically completely ignores the legacy json files, because the logic has been implemented in the denormalize() method of the content entity normalizer, which exclusively deals with YAML files. The code branch for json is higher op, in the importContent method of the importer class. I tried looking through this issue whether that was a deliberate decision, but I couldn't find any mention of it. To me this "smells" a little, it should really matter what format the input is in for this functionality to do its thing. Of course, when json support is completely removed this might all go away... Thoughts?
Comment #188
pfrenssenReplying to the comment from @eelkeblok in #2698425-187: Do not reimport existing entities:
This issue got raised before. It was suggested by @berdir in comment #2698425-161: Do not reimport existing entities that the old JSON format is basically unsupported and developers should update to YAML format when updating to 2.x.
Since there never was support for updating existing entities in 1.x and there never will be, there is no real reason to include JSON support in this issue. I agree that it would help to make the upgrade process smoother for people who were already using an early version of this patch for 1.x, but that shouldn't block adoption of this issue.
All remarks have been addressed, setting back to needs review.
Comment #189
johanvdr CreditAttribution: johanvdr commentedShould we not check for existing entities and update them instead of recreating all?
Comment #190
Mistrae CreditAttribution: Mistrae commentedPatch #173 works well. On the contrary with MR 14, if I import 2 different nodes with same images and medias on 2 different modules, one node has no image.
Comment #191
pfrenssen@Mistrae thanks for the report. Could you possibly provide a test case that shows the bug? Or more details on how this can be replicated?
Comment #192
jomsy CreditAttribution: jomsy commentedCould not apply the patch after upgrading to 2.0@alpha. Is it because the HAL module is made optional in the new version?
Comment #193
Eduardo Morales AlbertiComment #194
cvalverp CreditAttribution: cvalverp at NTT DATA commentedThanks for patch #175, we have tested it on drupal 9.5. And it works correctly.
Be careful with changing ID during import.
Comment #195
delacosta456 CreditAttribution: delacosta456 commentedhi
also thanks for #175 .. it's working on D10.2.5 with php8.2