从网上下载的一些数据,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 mysite
cd mysite
python manage.py startapp blog

把 blog 中的 models.py 更改为以下内容

1
2
3
4
5
6
7
8
9
10
11
#!/usr/bin/python
#coding:utf-8
 
from django.db import models
 
class 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 definition
INSTALLED_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, sessions
Synchronizing 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... OK
 
You have installed Django's auth system, and don't have any superusers defined.
Would you like to create one now? (yes/no): yes
Username (leave blank to use 'tu'): tu
Email 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 1
title 2****content 2
title 3****content 3
title 4****content 4
title 5****content 5
title 6****content 6
title 7****content 7
title 8****content 8
title 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-8
 
import os
os.environ.setdefault("DJANGO_SETTINGS_MODULE""mysite.settings"

)      这里很重要  引入project的setting,到project根目录的文件里面

 
'''
Django 版本大于等于1.7的时候,需要加上下面两句
import django
django.setup()
否则会抛出错误 django.core.exceptions.AppRegistryNotReady: Models aren't loaded yet.
'''
 
import django
if 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 python
import os
os.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 python
import os
os.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数据导入的更多相关文章

  1. [Django]数据批量导入

    前言:历经一个月的复习,考试终于结束了.这期间上班的时候有研究了Django网页制作过程中,如何将数据批量导入到数据库中. 这个过程真的是惨不忍睹,犯了很多的低级错误,这会在正文中说到的.再者导入数据 ...

  2. Django数据操作F和Q、model多对多操作、Django中间件、信号、读数据库里的数据实现分页

    models.tb.objects.all().using('default'),根据using来指定在哪个库里查询,default是settings中配置的数据库的连接名称. 外话:django中引 ...

  3. 使用openpyxl模块将Excel中的数据导入数据库

    这里将不介绍openpyxl模块的详细操作. 主要就是记录一个使用openpyxl模块将Excel表格的数据导入数据库中的实例. from openpyxl import load_workbook ...

  4. django后台导入excel文件

    1.django 如何从后台上传excel中批量解析数据 要从django后台导入的excel中批量解析数据,举一个例子,我们向后抬批量导入svn历史数据数据格式 假设excel表中有4列,每列分别是 ...

  5. Django模块导入

    Django模块导入篇 Django基础 urls.py 导入app中的视图函数 from app名字 import views app.view视图函数中导入models.py中的类 from ap ...

  6. ITTC数据挖掘平台介绍(五) 数据导入导出向导和报告生成

    一. 前言 经过了一个多月的努力,软件系统又添加了不少新功能.这些功能包括非常实用的数据导入导出,对触摸进行优化的画布和画笔工具,以及对一些智能分析的报告生成模块等.进一步加强了平台系统级的功能. 马 ...

  7. FineReport实现EXCEL数据导入自由报表

    在制作填报报表的时候,对于空白填报表,常常导出为Excel,派发给各部门人员填写后上交.如何能避免手动输入,直接将Excel中的数据导入到填报表中提交入库呢? 这里以一个简单的员工信息填报示例进行介绍 ...

  8. Execl数据导入sql server方法

    在日常的程序开发过程中,很多情况下,用户单位给予开发人员的数据往往是execl或者是access数据,如何把这些数据转为企业级是数据库数据呢,下面就利用sqlserver自带的功能来完成此项任务. 首 ...

  9. kettle将Excel数据导入oracle

    导读 Excel数据导入Oracle数据库的方法: 1.使用PL SQL 工具附带的功能,效率比较低 可参考这篇文章的介绍:http://www.2cto.com/database/201212/17 ...

随机推荐

  1. C+继承

    // 继承.cpp : Defines the entry point for the console application.// #include "stdafx.h" str ...

  2. Git 小技巧

    分享git的几个小技巧,后面会根据使用补充.目前包括git撤销本地修改.git回退到前n个版本.git多用户提交冲突解决.git 命令简化.欢迎大家补充^_* 1.git撤销本地修改 git rese ...

  3. 常用 Git 命令

    拉取远端仓库代码: 如果本地已经存在文件夹,先cd进去,然后敲命令: git fetch (作用是拉取远端仓库里的代码) git merge (作用是将远端仓库里的代码与本地仓库里的代码合并,如果有冲 ...

  4. hive 复杂类型

    hive提供一种复合类型的数据 struct:可以使用"."来存取数据 map:可以使用键值对来存取数据 array:array中存取的数据为相同类型,其中的数据可以通过下表获取数 ...

  5. NGUI之UIRoot——屏幕的自适应分辨率的计算

    //原来写在其他博客上的东西,搬迁 预备知识: 要明确的三个概念: 设计分辨率:在编辑器上开发UI使用的分辨率.我们所有的UI都是在这个分辨率下设计制作的. 显示区域分辨率:设备上所显示的UI区域在编 ...

  6. windows C++实现注销、重启、关机 logoff reboot shutdown

    实现这一功能很简单,主要需要调用一个系统API ExitWindowsEx 功能就是,注销当前用户,关闭系统,或者重新启动系统. 它会发送一个WM_QUERYENDSESSION消息给所有的应用程序, ...

  7. Foreach 原理

    public class Person { private string[] friends = { "asf", "ewrqwe", "ddd&qu ...

  8. tp框架之session

    系统提供了Session管理和操作的完善支持,全部操作可以通过一个内置的session函数完成,该函数可以完成Session的设置.获取.删除和管理操作. session初始化设置 如果session ...

  9. js倒计时

    /** * 启动,秒杀倒计时 * totalSecond:剩余秒数 * showTime(tm):回调函数,其中tm={day:"",hour:"",min:& ...

  10. UWP学习记录10-设计和UI之控件和模式7

    UWP学习记录10-设计和UI之控件和模式7 1.导航控件 Hub,中心控件,利用它你可以将应用内容整理到不同但又相关的区域或类别中. 中心的各个区域可按首选顺序遍历,并且可用作更具体体验的起始点. ...