# Merging 2 discourse forums

**URL:** https://meta.discourse.org/t/merging-2-discourse-forums/35060
**Category:** Support
**Created:** [October 29, 2015, 2:10pm UTC](https://meta.discourse.org/t/merging-2-discourse-forums/35060 "2015-10-29T14:10:43Z")
**Posts on this page:** 17
**Page:** 1

<div class="post-metadata">

### Author: ![jmamazo](https://avatars.discourse-cdn.com/v4/letter/j/22d042/32.png) [@jmamazo](https://meta.discourse.org/u/jmamazo)
#### Post date: [October 29, 2015, 2:10pm UTC](https://meta.discourse.org/t/merging-2-discourse-forums/35060/1 "2015-10-29T14:10:43Z")

</div>

Hello guys  
We have 2 working discourse forums and we would like to merge them.

Is there a nice simple way to do this?

thanks

---

<div class="post-metadata">

### Author: ![zogstrip](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/zogstrip/32/512781_2.png) [@zogstrip](https://meta.discourse.org/u/zogstrip)
#### Post date: [October 29, 2015, 2:35pm UTC](https://meta.discourse.org/t/merging-2-discourse-forums/35060/2 "2015-10-29T14:35:44Z")

</div>

Not that I know of. I guess you’d have to write an importer. Should be pretty easy to do since the db schema is the same 🙂

---

<div class="post-metadata">

### Author: ![skotperez](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/skotperez/32/121615_2.png) [@skotperez](https://meta.discourse.org/u/skotperez)
#### Post date: [August 4, 2016, 8:17am UTC](https://meta.discourse.org/t/merging-2-discourse-forums/35060/3 "2016-08-04T08:17:05Z")

</div>

@jmamazo did you do the merge the two discourse installations? Did you write an importer? I’m in the same situation…

---

<div class="post-metadata">

### Author: ![dax](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/dax/32/244677_2.png) [@dax](https://meta.discourse.org/u/dax)
#### Post date: [August 2, 2018, 4:15pm UTC](https://meta.discourse.org/t/merging-2-discourse-forums/35060/6 "2018-08-02T16:15:28Z")

</div>

> [@Discourse 2.1.0 beta 2 Release Notes](https://meta.discourse.org/t/discourse-2-1-0-beta-2-release-notes/90712):
>
> New features in 2.1.0 .beta2 Script to merge two Discourse sites We’ve been asked many times and now you can do it! The [script](https://github.com/discourse/discourse/commit/20ceadffaf629a26b0068bfbb7d1e724b823aa6b) will allow you to merge two Discourse forums into a single site by importing topics, posts, tags, groups and users. Not ready for production use yet. Plugin improvements Translator++, Solved and Assign plugins migrate to new DB.exec pattern because exec\_sql is deprecated Staff Notes added a widget settings to show staff notes under avatar instead of in name Adverti…

When the script will be ready to be used in production @neil will write a topic for that.

---

<div class="post-metadata">

### Author: ![thaidb](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/thaidb/32/68488_2.png) [@thaidb](https://meta.discourse.org/u/thaidb)
#### Post date: [August 22, 2018, 10:47am UTC](https://meta.discourse.org/t/merging-2-discourse-forums/35060/7 "2018-08-22T10:47:25Z")

</div>

Hello @neil  
Now version 's Discourse is 2.1.0 beta 5. At this time, Everything is available for merge 2 Discourse forum?  
Do we have step by step to merger them?  
Thank you!

---

<div class="post-metadata">

### Author: ![neil](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/neil/32/102150_2.png) [@neil](https://meta.discourse.org/u/neil)
#### Post date: [August 22, 2018, 9:12pm UTC](https://meta.discourse.org/t/merging-2-discourse-forums/35060/9 "2018-08-22T21:12:45Z")

</div>

I have started a wiki post here:

> [@Merge two Discourse sites into one](https://meta.discourse.org/t/how-to-merge-two-discourse-sites/95435):
>
> If you have two Discourse sites that you wish were one, this guide is for you. There’s a tool called [discourse\_merger](https://github.com/discourse/discourse/blob/main/script/bulk_import/discourse_merger.rb) that can take one Discourse site and merge it into another. Prereqs This is not an easy task, and should be treated like any other migration to Discourse. You will not be running discourse\_merger on a live production site. You will perform the merge in another environment where you can review the output before moving the result to production. Copy vs Merge Almost everythin…

---

<div class="post-metadata">

### Author: ![Walker\_Blackwell](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/walker_blackwell/32/119568_2.png) [@Walker\_Blackwell](https://meta.discourse.org/u/Walker_Blackwell)
#### Post date: [September 12, 2018, 4:56pm UTC](https://meta.discourse.org/t/merging-2-discourse-forums/35060/10 "2018-09-12T16:56:43Z")

</div>

Dear @neil. I have started this process but with little success.

It seems as though this discourse\_merger is defaulting to using the user “discourse” to peer with the postgres instead of user “postgres”. I am getting inevitable peer authentication errors no matter the environment I work with.

A more in-depth explanation of exactly what environment/docker you are working with (and how exactly you set this up from a start-point) to successfully get this working would be much appreciated. I’m currently using most recent stable beta btw.

best,  
Walker

---

<div class="post-metadata">

### Author: ![neil](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/neil/32/102150_2.png) [@neil](https://meta.discourse.org/u/neil)
#### Post date: [September 13, 2018, 3:47pm UTC](https://meta.discourse.org/t/merging-2-discourse-forums/35060/11 "2018-09-13T15:47:18Z")

</div>

I think there are some missing options for username, password in the initialize method:

> <https://github.com/discourse/discourse/blob/main/script/bulk_import/discourse_merger.rb#L18-L23>

If you’re still trying to get this work, try adding `user: ` and `password:` options for both of those connections and see if that fixes it.

---

<div class="post-metadata">

### Author: ![Walker\_Blackwell](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/walker_blackwell/32/119568_2.png) [@Walker\_Blackwell](https://meta.discourse.org/u/Walker_Blackwell)
#### Post date: [September 13, 2018, 4:10pm UTC](https://meta.discourse.org/t/merging-2-discourse-forums/35060/12 "2018-09-13T16:10:32Z")

</div>

Got it, will try. And thank you!!!

-Walker

---

<div class="post-metadata">

### Author: ![Walker\_Blackwell](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/walker_blackwell/32/119568_2.png) [@Walker\_Blackwell](https://meta.discourse.org/u/Walker_Blackwell)
#### Post date: [September 13, 2018, 4:25pm UTC](https://meta.discourse.org/t/merging-2-discourse-forums/35060/13 "2018-09-13T16:25:58Z")

</div>

I am going to try this and see.

```
def initialize
    local_db = ActiveRecord::Base.connection_config
    @raw_connection = PG.connect(dbname: local_db[:database], host: 'localhost', user: 'postgres', port: local_db[:port])

    @source_db_config = {
      dbname: ENV["DB_NAME"] || 'copyme',
      host: ENV["DB_HOST"] || 'localhost',
      user: ENV["DB_USER"] || 'postgres'
    }

```

---

<div class="post-metadata">

### Author: ![Walker\_Blackwell](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/walker_blackwell/32/119568_2.png) [@Walker\_Blackwell](https://meta.discourse.org/u/Walker_Blackwell)
#### Post date: [September 13, 2018, 4:57pm UTC](https://meta.discourse.org/t/merging-2-discourse-forums/35060/14 "2018-09-13T16:57:05Z")

</div>

It works with

`@raw_connection = PG.connect(dbname: local_db[:database], host: 'localhost', user: 'postgres', password: '<put your password here>', port: local_db[:port])`

It’s a hard-bake but at least it goes.

I had to do following to get password set:

```
sudo -u postgres psql postgres
\password postgres
(enter the new password)
\q

```

Now onto new and interesting bugs like unique constraints (instead of copy-over)!

best,  
Walker

---

<div class="post-metadata">

### Author: ![Walker\_Blackwell](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/walker_blackwell/32/119568_2.png) [@Walker\_Blackwell](https://meta.discourse.org/u/Walker_Blackwell)
#### Post date: [September 13, 2018, 5:29pm UTC](https://meta.discourse.org/t/merging-2-discourse-forums/35060/15 "2018-09-13T17:29:50Z")

</div>

Ok. So one (hopefully) more question.

I get this error right off the bat:

```
 .rvm/gems/ruby-2.5.1/gems/pg-1.1.0/lib/pg/connection.rb:173:in `get_last_result': ERROR: duplicate key value violates unique constraint "index_topic_users_on_topic_id_and_user_id" (PG::UniqueViolation)
    DETAIL: Key (topic_id, user_id)=(6233, 1213) already exists.
    CONTEXT: COPY topic_users, line 1437

```

Does this mean that if I have a topic\_id and user\_id combo that is identical on both databases this will not work?

If so, that will become a problem in some use-cases where there is one or two admins that are replying a LOT topics on both forums that want to be merged. Because the assumption on this action is that it’s uni-directional and there are ideally no duplicate posts between forums (only duplicate user emails) can this script update the post ID with a unique # if it hits this error?

best,  
Walker

---

<div class="post-metadata">

### Author: ![neil](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/neil/32/102150_2.png) [@neil](https://meta.discourse.org/u/neil)
#### Post date: [September 13, 2018, 5:49pm UTC](https://meta.discourse.org/t/merging-2-discourse-forums/35060/16 "2018-09-13T17:49:52Z")

</div>

I saw errors like that many many times while working on this and resolved all the times I saw it. Looks like there are more cases where it can happen.

> [@Walker\_Blackwell](#):
>
> Does this mean that if I have a topic\_id and user\_id combo that is identical on both databases this will not work?

No, it’s supposed to work. The users and topics will get new id’s after being copied, unless the user is matched to another user with the same email address.

Can you share more of the output above that error? Maybe I’ll be able to narrow it down.

---

<div class="post-metadata">

### Author: ![Walker\_Blackwell](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/walker_blackwell/32/119568_2.png) [@Walker\_Blackwell](https://meta.discourse.org/u/Walker_Blackwell)
#### Post date: [September 13, 2018, 6:09pm UTC](https://meta.discourse.org/t/merging-2-discourse-forums/35060/17 "2018-09-13T18:09:24Z")

</div>

Ok. I reset the VM to just before the first command and hit it.

Ubuntu 16.04 Discourse Dev setup. Maybe a timing issue?

Here’s the full output:

```
ijm@ubuntu:~/discourse$ IMPORT=1 DB_NAME=copyme DB_USER=postgres SOURCE_BASE_URL=http://127.0.0.1 UPLOADS_PATH=/home/ijm/uploads/default bundle exec ruby script/bulk_import/discourse_merger.rb
Loading application...
Starting...
Preloading I18n...
Fixing highest post numbers...
Loading imported group ids...
Loading imported user ids...
Loading imported category ids...
Loading imported topic ids...
Loading imported post ids...
Loading groups indexes...
Loading users indexes...
Loading categories indexes...
Loading topics indexes...
Loading posts indexes...
Loading post actions indexes...

merging users...
copying email_tokens...
copying user_emails...
copying user_stats...
copying user_options...
copying user_profiles...
copying user_visits...
copying user_search_data...
copying given_daily_likes...
copying user_second_factors...
copying user_open_ids...
copying facebook_user_infos...
copying github_user_infos...
copying google_user_infos...
copying instagram_user_infos...
copying oauth2_user_infos...
copying single_sign_on_records...
copying twitter_user_infos...
copying email_change_requests...
copying groups...
copying group_users...
merging categories...
copying topics...
copying topic_allowed_groups...
copying topic_allowed_users...
copying topic_embeds...
copying topic_search_data...
copying topic_timers...
copying topic_users...
Traceback (most recent call last):
	9: from script/bulk_import/discourse_merger.rb:799:in `<main>'
	8: from script/bulk_import/discourse_merger.rb:67:in `start'
	7: from /home/ijm/discourse/script/bulk_import/base.rb:81:in `run'
	6: from script/bulk_import/discourse_merger.rb:81:in `execute'
	5: from script/bulk_import/discourse_merger.rb:233:in `copy_topics'
	4: from script/bulk_import/discourse_merger.rb:233:in `each'
	3: from script/bulk_import/discourse_merger.rb:234:in `block in copy_topics'
	2: from script/bulk_import/discourse_merger.rb:407:in `copy_model'
	1: from /home/ijm/.rvm/gems/ruby-2.5.1/gems/pg-1.1.0/lib/pg/connection.rb:173:in `copy_data'
/home/ijm/.rvm/gems/ruby-2.5.1/gems/pg-1.1.0/lib/pg/connection.rb:173:in `get_last_result': ERROR: duplicate key value violates unique constraint "index_topic_users_on_topic_id_and_user_id" (PG::UniqueViolation)
DETAIL: Key (topic_id, user_id)=(6231, 1213) already exists.
CONTEXT: COPY topic_users, line 1437

```

---

<div class="post-metadata">

### Author: ![neil](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/neil/32/102150_2.png) [@neil](https://meta.discourse.org/u/neil)
#### Post date: [September 13, 2018, 10:07pm UTC](https://meta.discourse.org/t/merging-2-discourse-forums/35060/18 "2018-09-13T22:07:50Z")

</div>

No it shouldn’t be a timing issue.

I can’t see what needs to be changed when copying topic\_users… Are you re-running the script on a database that has already had the tool run against it? Be sure that you are restoring the database back to before you ran the script. I guess you did that because you probably would have hit an error earlier… 🤔

It’s very hard to debug this without some real data.

---

<div class="post-metadata">

### Author: ![justin](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/justin/32/157614_2.png) [@justin](https://meta.discourse.org/u/justin)
#### Post date: [January 8, 2021, 3:44pm UTC](https://meta.discourse.org/t/merging-2-discourse-forums/35060/19 "2021-01-08T15:44:36Z")

</div>

Most of this stuff has been answered now in the merger howto.

> [@Merge two Discourse sites into one](https://meta.discourse.org/t/how-to-merge-two-discourse-sites/95435):
>
> If you have two Discourse sites that you wish were one, this guide is for you. There’s a tool called [discourse\_merger](https://github.com/discourse/discourse/blob/main/script/bulk_import/discourse_merger.rb) that can take one Discourse site and merge it into another. Prereqs This is not an easy task, and should be treated like any other migration to Discourse. You will not be running discourse\_merger on a live production site. You will perform the merge in another environment where you can review the output before moving the result to production. Copy vs Merge Almost everythin…

---

<div class="post-metadata">

### Author: ![justin](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/justin/32/157614_2.png) [@justin](https://meta.discourse.org/u/justin)
#### Post date: [January 8, 2021, 3:44pm UTC](https://meta.discourse.org/t/merging-2-discourse-forums/35060/20 "2021-01-08T15:44:41Z")

</div>


