Django数据导入
从网上下载的一些数据,excel表格,xml文件,txt文件等有时候我们想把它导入数据库,应该如何操作呢?
以下操作符合 Django版本为 1.6 ,兼顾 Django 1.7, Django 1.8 版本,理论上Django 1.4, 1.5 也没有问题,没有提到的都是默认值
备注:你可能会问数据从哪儿来的,比如你用python从以前的blog上获取过来的,想导入现在的博客,或者别人整理好的数据,或者你自己整理的excel表,一个个地在网站后台复制粘贴你觉得好么?这就是批量导入的必要性。
下载本教程源代码:
mysite.zip
建议先不要看源码,按教程一步步做下去,遇到问题再试试源代码,直接复制粘贴,很快就会忘掉,自己动手打一遍
我们新建一个项目 mysite, 再新建一个 app,名称为blog
|
1
2
3
|
django-admin.py startproject mysitecd mysitepython manage.py startapp blog |
把 blog 中的 models.py 更改为以下内容
|
1
2
3
4
5
6
7
8
9
10
11
|
#!/usr/bin/python#coding:utf-8from django.db import modelsclass Blog(models.Model): title = models.CharField(max_length=100) content = models.TextField() def __unicode__(self): return self.title |
不要忘了把 blog 加入到 settings.py 中的 INSTALLED_APPS 中。
|
1
2
3
4
5
6
7
|
# Application definitionINSTALLED_APPS = ( ... # 添加上 blog 这个 app 'blog',) |
一,同步数据库,创建相应的表
|
1
|
python manage.py syncdb |
Django 1.6以下版本会看到:

Django 创建了一些默认的表,注意后面那个红色标记的blog_blog是appname_classname的样式,这个表是我们自己写的Blog类创建的
Django 1.7.6及以上的版本会看到:(第六行即为创建了对应的blog_blog表)
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
Operations to perform: Synchronize unmigrated apps: blog Apply all migrations: admin, contenttypes, auth, sessionsSynchronizing apps without migrations: Creating tables... Creating table blog_blog Installing custom SQL... Installing indexes...Running migrations: Applying contenttypes.0001_initial... OK Applying auth.0001_initial... OK Applying admin.0001_initial... OK Applying sessions.0001_initial... OKYou have installed Django's auth system, and don't have any superusers defined.Would you like to create one now? (yes/no): yesUsername (leave blank to use 'tu'): tuEmail address: Password: Password (again): Superuser created successfully. |
二,输入 python manage.py shell
进入该项目的django环境的终端(windows如何进入对应目录?看 Django环境搭建 的 3.2 部分)
先说如何用命令新增一篇文章:
|
1
2
3
4
|
$ python manage.py shell>>> from blog.models import Blog>>> Blog.objects.create(title="The first blog of my site", content="I am writing my blog on Terminal") |
这样就新增了一篇博文,我们查看一下
|
1
2
|
>>> Blog.objects.all() # 获取所有blog[<Blog: The first blog of my site>] |
还有两种方法(这两种差不多):
|
1
2
3
4
5
6
7
|
>>> blog2 = Blog()>>> blog2.title = "title 2">>> blog2.content = "content 2">>> blog2.save()或者>>> blog2 = Blog(title="title 2",content="content 2")>>> blog2.save() |
后面两种方法也很重要,尤其是用在修改数据的时候,要记得最后要保存一下 blog.save(),第一种Blog.objects.create()是自动保存的。
三,批量导入
比如我们要导入一个文本,里面是标题和内容,中间用四个*隔开的,示例(oldblog.txt):
|
1
2
3
4
5
6
7
8
9
|
title 1****content 1title 2****content 2title 3****content 3title 4****content 4title 5****content 5title 6****content 6title 7****content 7title 8****content 8title 9****content 9 |
在终端导入有时候有些不方便,我们在 最外面那个 mysite目录下写一个脚本,叫 txt2db.py,把 oldblog.txt 也放在mysite下
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
#!/usr/bin/env python#coding:utf-8import osos.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings"
'''Django 版本大于等于1.7的时候,需要加上下面两句import djangodjango.setup()否则会抛出错误 django.core.exceptions.AppRegistryNotReady: Models aren't loaded yet.'''import djangoif django.VERSION >= (1, 7):#自动判断版本 django.setup()def main(): from blog.models import Blog f = open('oldblog.txt') for line in f: title,content = line.split('****') Blog.objects.create(title=title,content=content) f.close()if __name__ == "__main__": main() print('Done!') |
这里如果oldblog.txt要全地址的话要这样:
open("C:\\Users\\Rajrishi\\Documents\\MyJava\\text.txt") # meh
open(r"C:\Users\Rajrishi\Documents\MyJava\text.txt") # better
open("C:/Users/Rajrishi/Documents/MyJava/text.txt") # also possible
可能是因为\有转义字符的意思,所以settings里面都是用/
好了,我们在终端运行它
|
1
2
|
python txt2db.py# 运行完后显示 一个 Done! 导入完成! |
运行完毕后会打出一个 "Done!", 数据已经全部导入!
四,导入数据重复 解决办法
如果你导入数据过多,导入时出错了,或者你手动停止了,导入了一部分,还有一部分没有导入。或者你再次运行上面的命令,你会发现数据重复了,怎么办呢?
django.db.models 中还有一个函数叫 get_or_create() 有就获取过来,没有就创建,用它可以避免重复,但是速度可以会慢些,因为要先尝试获取,看看有没有
只要把上面的
|
1
|
Blog.objects.create(title=title,content=content) |
换成下面的就不会重复导入数据了
|
1
|
Blog.objects.get_or_create(title=title,content=content) |
返回值是(BlogObject, True/False) 新建时返回 True, 已经存在时返回 False。
更多数据库API的知识请参见官网文档:QuerySet API
五, 用fixture导入
最常见的fixture文件就是用python manage.py dumpdata 导出的文件,示例如下:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
[ { "model": "myapp.person", "pk": 1, "fields": { "first_name": "John", "last_name": "Lennon" } }, { "model": "myapp.person", "pk": 2, "fields": { "first_name": "Paul", "last_name": "McCartney" } }] |
你也可以根据自己的models,创建这样的json文件,然后用 python manage.py loaddata fixture.json 导入
详见:https://docs.djangoproject.com/en/dev/howto/initial-data/
可以写一个脚本,把要导入的数据转化成 json 文件,这样导入也会更快些!
六,Model.objects.bulk_create() 更快更方便
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
#!/usr/bin/env pythonimport osos.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings")def main(): from blog.models import Blog f = open('oldblog.txt') BlogList = [] for line in f: title,content = line.split('****') 高能分词 blog = Blog(title=title,content=content) BlogList.append(blog) f.close() Blog.objects.bulk_create(BlogList)if __name__ == "__main__": main() print('Done!') |
由于Blog.objects.create()每保存一条就执行一次SQL,而bulk_create()是执行一条SQL存入多条数据,做会快很多!当然用列表解析代替 for 循环会更快!!
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
#!/usr/bin/env pythonimport osos.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings")def main(): from blog.models import Blog f = open('oldblog.txt') BlogList = [] for line in f: parts = line.split('****') BlogList.append(Blog(title=parts[0], content=parts[1])) f.close() # 以上四行 也可以用 列表解析 写成下面这样 # BlogList = [Blog(title=line.split('****')[0], content=line.split('****')[1]) for line in f] Blog.objects.bulk_create(BlogList)if __name__ == "__main__": 这招有点像c语言的main函数定义入口 main() print('Done!') |
Django数据导入的更多相关文章
- [Django]数据批量导入
前言:历经一个月的复习,考试终于结束了.这期间上班的时候有研究了Django网页制作过程中,如何将数据批量导入到数据库中. 这个过程真的是惨不忍睹,犯了很多的低级错误,这会在正文中说到的.再者导入数据 ...
- Django数据操作F和Q、model多对多操作、Django中间件、信号、读数据库里的数据实现分页
models.tb.objects.all().using('default'),根据using来指定在哪个库里查询,default是settings中配置的数据库的连接名称. 外话:django中引 ...
- 使用openpyxl模块将Excel中的数据导入数据库
这里将不介绍openpyxl模块的详细操作. 主要就是记录一个使用openpyxl模块将Excel表格的数据导入数据库中的实例. from openpyxl import load_workbook ...
- django后台导入excel文件
1.django 如何从后台上传excel中批量解析数据 要从django后台导入的excel中批量解析数据,举一个例子,我们向后抬批量导入svn历史数据数据格式 假设excel表中有4列,每列分别是 ...
- Django模块导入
Django模块导入篇 Django基础 urls.py 导入app中的视图函数 from app名字 import views app.view视图函数中导入models.py中的类 from ap ...
- ITTC数据挖掘平台介绍(五) 数据导入导出向导和报告生成
一. 前言 经过了一个多月的努力,软件系统又添加了不少新功能.这些功能包括非常实用的数据导入导出,对触摸进行优化的画布和画笔工具,以及对一些智能分析的报告生成模块等.进一步加强了平台系统级的功能. 马 ...
- FineReport实现EXCEL数据导入自由报表
在制作填报报表的时候,对于空白填报表,常常导出为Excel,派发给各部门人员填写后上交.如何能避免手动输入,直接将Excel中的数据导入到填报表中提交入库呢? 这里以一个简单的员工信息填报示例进行介绍 ...
- Execl数据导入sql server方法
在日常的程序开发过程中,很多情况下,用户单位给予开发人员的数据往往是execl或者是access数据,如何把这些数据转为企业级是数据库数据呢,下面就利用sqlserver自带的功能来完成此项任务. 首 ...
- kettle将Excel数据导入oracle
导读 Excel数据导入Oracle数据库的方法: 1.使用PL SQL 工具附带的功能,效率比较低 可参考这篇文章的介绍:http://www.2cto.com/database/201212/17 ...
随机推荐
- xcode 8 重新支持插件
苹果出了Xcode8之后,就加了签名让之前的自定义插件无法继续的安装使用.想要重新使用插件的话只要用自己的签名覆盖苹果的签名即可. 1.创建自签名证书 钥匙串->钥匙串访问->证书助理-& ...
- 3ds max旋转简化后模型
简化后的模型无法与原场景直接匹配,因此需要以下步骤: 简化后的模型导入,原点在右上角 旋转后,方法是选中所有模型,右键->旋转 在偏移的x和y各输入180 还有做一些平移,微调 在导入整个she ...
- MVC之Model转Json
在开发中,有时我们需要在View层中拿到Model返回的数据并且是一个Json对象,那么我们就可以利用Newtonsoft.Json.JsonConvert.SerializeObject(Model ...
- 重装系统后如何删除系统自带的office2003
背景:操作系统重装后,系统自带的office2003版本太低不好使用,需要安装更高版本的如2010,但是卸载时提示“无法打开此修补程序包……”,从而无法卸载.经网上查询,采用以下解决办法: 在注册表中 ...
- C#重启IIS指定网站和指定应用程序池
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
- 四、线程同步之Lock和Condition
Lock同步锁 Lock 在jdk1.5 提供了Lock以便执行同步操作,和synchronized不同的是Lock提供了显示的方法获取锁和释放锁.Lock提供了以下几个方法,请求和释放锁: voi ...
- Flashback Data Archive ( Oracle Total Recall ) introduced in 11g
Flashback Data Archive feature is part of Oracle Total Recall technology. Flashback Data Archive fea ...
- 表单验证<AngularJs>
常用的表单验证指令 1. 必填项验证 某个表单输入是否已填写,只要在输入字段元素上添加HTML5标记required即可: <input type="text" requir ...
- httpclient 无信任证书使用https
1.当不需要使用任何证书访问https网页时,只需配置信任任何证书 HttpClient http = new HttpClient(); String url = "https://pay ...
- laravel 框架使用总结 limit
后台开发就是数据的各种处理很多时候需要做到分页,但是在laravel中使用limit做分页的时候会出现问题,偏移量和每页的条数放进去好像不好使了 下面推荐给大家一种在laravel框架中非常好用的写法 ...