Repository: Cog-Creators/Red-DiscordBot

Issue:
Cannot convert from JSON to MongoDB
# Other bugs

<!-- 
Did you find a bug with something other than a command? Fill out the following:
-->

#### What were you trying to do?

<!-- Replace this line with a description of what you were trying to do -->

Edit an instance to modify its storage type from JSON to MongoDB.

#### What were you expecting to happen?

<!-- Replace this line with a description of what you were expecting to happen -->

Convert the JSON data to the MongoDB scheme.

#### What actually happened?

<!-- Replace this line with a description of what actually happened. Include any error messages -->

```py
Please choose your storage backend (if you re unsure, choose 1).
1. JSON (file storage, requires no database).
2. MongoDB
> 2
Enter URI scheme (mongodb or mongodb+srv): mongodb
Enter host address: 127.0.0.1:27017
Enter login username:
Enter login password:
Enter mongodb database name: Oxibot
Would you like to import your data? (y/n) y
Traceback (most recent call last):
  File "/usr/local/bin/redbot-setup", line 11, in <module>
    load_entry_point('Red-DiscordBot==3.0.0rc2', 'console_scripts', 'redbot-setup')()
  File "/usr/local/lib/python3.6/dist-packages/redbot/setup.py", line 384, in main
    loop.run_until_complete(edit_instance())
  File "/usr/lib/python3.6/asyncio/base_events.py", line 467, in run_until_complete
    return future.result()
  File "/usr/local/lib/python3.6/dist-packages/redbot/setup.py", line 278, in edit_instance
    await json_to_mongo(current_data_dir, storage_details)
  File "/usr/local/lib/python3.6/dist-packages/redbot/setup.py", line 198, in json_to_mongo
    {"_id": cog_m.unique_cog_identifier}, update={"$set": cog_data[cog_i]}, upsert=True
KeyError: '-4851999857783813997'
```

#### How can we reproduce this issue?

<!-- Replace with numbered steps to reproduce the issue -->

According to Crossedfall, this seems to happen with 3rd party cogs, but I can't give more details, the error does not details which file the bot was editing, and there's no logger in `redbot-setup`.


Discussion:
I am getting an error similar to the one above doing the same steps.

```Traceback (most recent call last):
  File "/home/lailah/bots/bin/redbot-setup", line 11, in <module>
    load_entry_point('Red-DiscordBot==3.0.0rc2', 'console_scripts',
'redbot-setup')()
  File "/home/lailah/bots/lib/python3.6/site-packages/redbot/setup.py",
line 384, in main
    loop.run_until_complete(edit_instance())
  File "/usr/lib/python3.6/asyncio/base_events.py", line 468, in
run_until_complete
    return future.result()
  File "/home/lailah/bots/lib/python3.6/site-packages/redbot/setup.py",
line 278, in edit_instance
    await json_to_mongo(current_data_dir, storage_details)
  File "/home/lailah/bots/lib/python3.6/site-packages/redbot/setup.py",
line 198, in json_to_mongo
    {"_id": cog_m.unique_cog_identifier}, update={"$set":
cog_data[cog_i]}, upsert=True
KeyError: '-2039828293'```
Can confirm that this is an issue.

Resolving patch:
diff --git a/redbot/setup.py b/redbot/setup.py
--- a/redbot/setup.py
+++ b/redbot/setup.py
@@ -1,5 +1,4 @@
-#!/usr/bin/env python
-
+#!/usr/bin/env python3
 import argparse
 import asyncio
 import json
@@ -177,26 +176,21 @@ def basic_setup():
 async def json_to_mongo(current_data_dir: Path, storage_details: dict):
     from redbot.core.drivers.red_mongo import Mongo
 
-    core_data_file = list(current_data_dir.glob("core/settings.json"))[0]
-    m = Mongo("Core", "0", **storage_details)
+    core_data_file = current_data_dir / "core" / "settings.json"
+    driver = Mongo(cog_name="Core", identifier="0", **storage_details)
     with core_data_file.open(mode="r") as f:
         core_data = json.loads(f.read())
-    collection = m.get_collection()
-    await collection.update_one(
-        {"_id": m.unique_cog_identifier}, update={"$set": core_data["0"]}, upsert=True
-    )
+    data = core_data.get("0", {})
+    for key, value in data.items():
+        await driver.set(key, value=value)
     for p in current_data_dir.glob("cogs/**/settings.json"):
+        cog_name = p.parent.stem
         with p.open(mode="r") as f:
-            cog_data = json.loads(f.read())
-        cog_i = None
-        for ident in list(cog_data.keys()):
-            cog_i = str(hash(ident))
-        cog_m = Mongo(p.parent.stem, cog_i, **storage_details)
-        cog_c = cog_m.get_collection()
-        for ident in list(cog_data.keys()):
-            await cog_c.update_one(
-                {"_id": cog_m.unique_cog_identifier}, update={"$set": cog_data[cog_i]}, upsert=True
-            )
+            cog_data = json.load(f)
+        for identifier, data in cog_data.items():
+            driver = Mongo(cog_name, identifier, **storage_details)
+            for key, value in data.items():
+                await driver.set(key, value=value)
 
 
 async def mongo_to_json(current_data_dir: Path, storage_details: dict):


Test patch: