如何使用 Django ORM 将 JSON 文件中的数据加载到 MySQL 实例中?

Posted

技术标签:

【中文标题】如何使用 Django ORM 将 JSON 文件中的数据加载到 MySQL 实例中?【英文标题】:How to load data from JSON files into MySQL instance with the Django ORM? 【发布时间】:2019-09-25 16:14:42 【问题描述】:

我正在使用 Django 构建一个 ETL 引擎,并且我已经构建了一些方法来从一些 API 端点提取和转换数据,这些端点以 .JSON 格式保存到我的机器上。文件格式命名如下:repos_transformed_2019-05-06-13-23-59.jsonrepos_extraction_2019-05-06-13-23-59.json,以防对 Django ORM 的查找很重要。

我有一个 mysql 实例正在运行,其架构与我的 .JSON 文件中定义的键完全匹配,但 Django ORM 没有从loaddata 命令将数据加载到我的数据库中。我必须手动创建模型的一个实例并手动对其进行硬编码。显然,这在生产环境中是行不通的,我正试图找到一种方法将这些数据加载到 .json 文件“批次”中,而无需手动处理。

阅读文档(特别是 loaddata)后,我正尝试将其加载到我的数据库中,如下所示:

django-admin loaddata repos_transformed_2019-05-06-13-23-59.json --database invisible-hand

由于某种原因,我收到设置错误:

django.core.exceptions.ImproperlyConfigured: Requested setting TEMPLATES, but settings are not configured. You must either define the environment variable DJANGO_SETTINGS_MODULE or call settings.configure() before accessing settings.

这是我转换后的 .JSON 文件的 sn-p:

['repo_id': 20661, 'repo_name': 'Edge', 'creation_date': '2018-09-29T21:28:51Z', 'last_updated': '2018-12-05T19:30:11Z', 'watchers': 0, 'forks_count': 0, 'issues_count': 0, 'main_language': 'CSS', 'repo_size': 4252, ...]

这里是 MySQL 架构:

mysql> describe app_repository;
+---------------+------------------+------+-----+---------+-------+
| Field         | Type             | Null | Key | Default | Extra |
+---------------+------------------+------+-----+---------+-------+
| creation_date | varchar(21)      | YES  |     | NULL    |       |
| last_updated  | varchar(30)      | YES  |     | NULL    |       |
| main_language | varchar(30)      | YES  |     | NULL    |       |
| qty_forks     | int(10) unsigned | YES  |     | NULL    |       |
| qty_issues    | int(10) unsigned | YES  |     | NULL    |       |
| qty_watchers  | int(10) unsigned | YES  |     | NULL    |       |
| repo_id       | int(10) unsigned | YES  |     | NULL    |       |
| repo_name     | varchar(50)      | NO   | PRI | NULL    |       |
| repo_size     | int(10) unsigned | YES  |     | NULL    |       |
+---------------+------------------+------+-----+---------+-------+

我可以输入shell 并像docs 一样手动输入数据,但这不是解决问题的可扩展解决方案。

我希望能够将.JSON 文件自动同步到各自的表中。

我所有提取和转换的 .json 文件都存储在 /django_project_name/django_app_name/fixtures 和我的 settings.py 文件中,我设置了夹具文件路径:

# Fixtures that get loaded into the DB instance
FIXTURE_DIRS = (
    '/django_project_name/django_app_name/fixtures',
)

我的模板结构如下:

├── django_project_name
│   ├── django_app_name
│   │   ├── __init__.py
│   │   ├── __pycache__
│   │   │   ├── __init__.cpython-37.pyc
│   │   │   ├── admin.cpython-37.pyc
│   │   │   ├── models.cpython-37.pyc
│   │   │   ├── urls.cpython-37.pyc
│   │   │   └── views.cpython-37.pyc
│   │   ├── admin.py
│   │   ├── apps.py
│   │   ├── migrations
│   │   │   ├── 0001_initial.py
│   │   │   ├── 0002_auto_20190506_1238.py
│   │   │   ├── 0003_auto_20190506_1629.py
│   │   │   ├── __init__.py
│   │   │   └── __pycache__
│   │   │       ├── 0001_initial.cpython-37.pyc
│   │   │       ├── 0002_auto_20190506_1238.cpython-37.pyc
│   │   │       ├── 0003_auto_20190506_1629.cpython-37.pyc
│   │   │       └── __init__.cpython-37.pyc
│   │   ├── models.py
│   │   ├── templates
│   │   │   └── app
│   │   │       ├── discussions.html
│   │   │       ├── repositories.html
│   │   │       ├── repository.html
│   │   │       ├── team_members.html
│   │   │       └── teams.html
│   │   ├── tests.py
│   │   ├── urls.py
│   │   └── views.py
│   ├── db.sqlite3
│   ├── fixtures
│   │   ├── initial_data.json
│   │   ├── repos_extraction_2019-05-06-13-23-59.json
│   │   ├── repos_transformed_2019-05-06-13-23-59.json
│   │   ├── teams_extraction_2019-05-06-15-49-47.json
│   │   └── teams_transformed_2019-05-06-15-49-47.json
│   ├── iHand
│   │   ├── __init__.py
│   │   ├── __pycache__
│   │   │   ├── __init__.cpython-37.pyc
│   │   │   ├── settings.cpython-37.pyc
│   │   │   ├── urls.cpython-37.pyc
│   │   │   └── wsgi.cpython-37.pyc
│   │   ├── settings.py
│   │   ├── urls.py
│   │   └── wsgi.py
│   └── manage.py

如果能获得加载此数据的解决方案,我将不胜感激!非常感谢您的时间和帮助!干杯!

【问题讨论】:

【参考方案1】:

在json数据上使用loaddata,文件的结构必须是:

 "model": "", "pk": ID, "fields": OriginalJsonData 

您可以在加载数据之前运行这个简短的脚本来转换为正确的 json 结构

import json

file_name='YOUR_JSON_DATA_FILE'
pk = 0
new_list = []

with open('.json'.format(file_name)) as json_data:
    d = json.load(json_data)    
    for item in d:
        pk+=1
        item = "model": "modelname.modelname", "pk": pk, "fields": item
        new_list.append(item)
        json_data.close()


def list_to_json_file(list_of_dicts, file_name):
    with open(file_name+'.json', 'w') as file:
        json.dump(list_of_dicts, file)
    print('.Json file created'.format(file_name))


list_to_json_file(new_list, 'JSON_for_django')

然后在新的 json 文件上使用loaddata

在此过程之后不要再次忘记makemigrationsmigrate

【讨论】:

以上是关于如何使用 Django ORM 将 JSON 文件中的数据加载到 MySQL 实例中?的主要内容,如果未能解决你的问题,请参考以下文章

如何在不使用字段名的情况下运行 django orm 查询?

如何将 Django 频道会话分配给 ORM 中的对象?

如何使用 django orm 将数据插入到多个表中

如何在django系统外使用django的ORM

如何将Django ORM连接到mongo atlas?

如何使用 Django ORM 将注释字符串转换为布尔值