精华内容
下载资源
问答
  • 主要介绍了Django修改app名称和数据迁移方案实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
  • 跨数据库数据迁移

    2017-12-22 10:16:05
    * 有数据从源表中查询到数据时被调用,直到任务完成 * result 查询结果 * start 查询起始行 * end 查询结束行 * time 共耗时 单位:ms * e 查询失败时抛出的异常 * insertDone(boolean result, int num, int ...
  • 定义好模型之后,需要进行数据迁移,即将定义的模型在数据库中生成对应的table。步骤如下: (1)检查模型,运行 python manage.py check ,看模型是否有误; (2)创建迁移,运行 python manage.py ...

    创建app(假设其名为myapp)之后,定义其模型,即Model;
    在myapp目录下面,有一个文件为models.py,模型的定义就在此处。

    定义好模型之后,在settings.py中添加myapp,即在INSTALLED_APPS中,添加一行“myapp”。

    定义好模型之后,需要进行数据迁移,即将定义的模型在数据库中生成对应的table。步骤如下:
    (1)检查模型,运行python manage.py check,看模型是否有误;
    (2)创建迁移,运行python manage.py makemigrations myapp,此命令会在myapp目录下的
    migrations子目录中生成一个迁移文件“0001_initial.py”;
    (3)根据迁移文件,生成迁移SQL语句,运行python manage.py sqlmigrate myapp 0001,此命
    令会生成创建table的sql语句,但不会执行。可以将这些语句拷贝到数据库客户端中执行,也可以根
    据第四步来执行;
    (4) 执行迁移sql语句,执行python manage.py migrate

    至此,可以在数据库中生成myapp中定义的模型对应的table。

    --------------------------------------

    扫一扫,关注我们,获取更多...

    转载于:https://my.oschina.net/aomojan/blog/1845903

    展开全文
  • python爬取app数据

    千次阅读 2019-06-28 15:48:10
    Pandas(Python Data Analysis Library)基于Numpy构建,让基于Numpy的应用更简单,被广泛应用于金融行业,流行的数据分析工具 将多个dict转成list的合集 import pandas as pd data = [ {'A': 'A1','B': 'B2','C'...

    python环境部署

    python环境部署这里不做叙述

    MYSQL操作

    安装MySQL驱动
    由于MySQL服务器以独立的进程运行,并通过网络对外服务,所以,需要支持Python的MySQL驱动来连接到MySQL服务器。MySQL官方提供了mysql-connector-python驱动,但是安装的时候需要给pip命令加上参数–allow-external:

    $ pip install mysql-connector-python --allow-external mysql-connector-python
    如果上面的命令安装失败,可以试试另一个驱动:

    $ pip install mysql-connector
    我们演示如何连接到MySQL服务器的test数据库:

    导入MySQL驱动:

    import mysql.connector

    注意把password设为你的root口令:

    conn = mysql.connector.connect(user=‘root’, password=‘password’, database=‘test’)
    cursor = conn.cursor()

    创建user表:

    cursor.execute(‘create table user (id varchar(20) primary key, name varchar(20))’)

    插入一行记录,注意MySQL的占位符是%s:

    cursor.execute(‘insert into user (id, name) values (%s, %s)’, [‘1’, ‘Michael’])
    cursor.rowcount
    1

    提交事务:

    conn.commit()
    cursor.close()

    运行查询:

    cursor = conn.cursor()
    cursor.execute(‘select * from user where id = %s’, (‘1’,))
    values = cursor.fetchall()
    values
    [(‘1’, ‘Michael’)]

    关闭Cursor和Connection:

    cursor.close()
    True

    conn.close()
    由于Python的DB-API定义都是通用的,所以,操作MySQL的数据库代码和SQLite类似。

    小结
    执行INSERT等操作后要调用commit()提交事务;

    MySQL的SQL占位符是%s。

    cookie操作

    序言
    我们在使用爬虫的时候,经常会用到cookie进行模拟登陆和访问。在使用urllib库做爬虫,我们需要借助http.cookiejar库中的CookieJar来实现。

    安装cookiejar库
    一般http库已经包含了cookiejar,如果没有那么使用pip install --upgrade cookiejar即可

    CookieJar类的子类:

    CookieJar:管理HTTP cookie值、存储HTTP请求生成的cookie、向传出的HTTP请求添加cookie的对象。整个cookie都存储在内存中,对CookieJar实例进行垃圾回收后cookie也将丢失。

    FileCookieJar:从CookieJar派生而来,用来创建FileCookieJar实例,检索cookie信息并将cookie存储到文件中。filename是存储cookie的文件名。delayload为True时支持延迟访问访问文件,即只有在需要时才读取文件或在文件中存储数据。

    MozillaCookieJar:从FileCookieJar派生而来,创建与Mozilla浏览器 cookies.txt兼容的FileCookieJar实例。

    LWPCookieJar:从FileCookieJar派生而来,创建与libwww-perl标准的 Set-Cookie3 文件格式兼容的FileCookieJar实例。

    代码示例
    获取cookie

    # -*- coding: utf-8 -*-
    from urllib import request
    from http import cookiejar
    
    
    class Cookie:
        def get_ccokie(self, url='http://www.baidu.com'):
            # 创建cookiejar实例对象
            cookie = cookiejar.CookieJar()
            print(cookie)
    
        #创建管理器
        cookie_handler = request.HTTPCookieProcessor(cookie)
        http_handler = request.HTTPHandler()
        https_handler = request.HTTPSHandler()
    
        #创建请求管理器
        opener = request.build_opener(cookie_handler,http_handler,https_handler)
    
        #发起请求
        url = url if url.strip() != '' else 'http://www.baidu.com'
        req = request.Request(url)
        response = opener.open(req)
    
        # 查看请求结果
        print(response.reason)  # OK
        print(cookie)
        return cookie
    
    # 保存cookie到文件
    def save_cookie(self, url='http://www.baidu.com'):
        # 创建cookiejar实例对象
        cookie = cookiejar.MozillaCookieJar("cookie.txt")
        print(cookie)
        # <MozillaCookieJar[]>
    
        # 创建管理器
        cookie_handler = request.HTTPCookieProcessor(cookie)
        http_handler = request.HTTPHandler()
        https_handler = request.HTTPSHandler()
    
        # 创建请求求管理器
        opener = request.build_opener(cookie_handler, http_handler, https_handler)
    
    
        req = request.Request(url)
    
        # 发起请求
        response = opener.open(req)
    
        # 查看请求结果
        print(response.reason)  # OK
        cookie.save()
    
    #从文件读取cookie
    def load_cookie(self, url='http://www.baidu.com', file='cookie.txt'):
        # 创建cookiejar实例对象
        cookie = cookiejar.MozillaCookieJar()
        cookie.load(file)
        print(cookie)
        # <MozillaCookieJar[<Cookie password=123456 for .httpbin.org/>, <Cookie username=pengshiyu for .httpbin.org/>]>
    
        # 创建管理器
        cookie_handler = request.HTTPCookieProcessor(cookie)
        http_handler = request.HTTPHandler()
        https_handler = request.HTTPSHandler()
    
        # 创建请求求管理器
        opener = request.build_opener(cookie_handler, http_handler, https_handler)
    
        req = request.Request(url)
    
        # 发起请求
        response = opener.open(req)
    
        # 查看请求结果
        print(response.reason)  # OK
        print(response.read())
        return response.read()
    

    app抓取实例

    环境

    以有银子app为实例

    所需扩展库

    requests库(一种http扩展库)
    教程参考: https://www.liaoxuefeng.com/wiki/1016959663602400/1183249464292448

    pip install  --upgrade requests
    

    BeautifulSoup(html解析库,可能还需要安装lxml库)
    教程参考:
    https://www.crummy.com/software/BeautifulSoup/bs4/doc/index.zh.html#id15
    安装

    pip install  --upgrade BeautifulSoup4
    

    如果执行报错:

    	To get rid of this warning, pass the additional argument 'features="html5lib"' to the BeautifulSoup constructor
    

    说明没有找到合适的解析器,可能是标准的html解析器无法使用,安装第三方的解析器 lxml .

    pip install --upgrade  lxml
    

    xlwings (execl处理库)

    pip install  --upgrade xlwings
    

    教程参考:
    https://blog.csdn.net/asanscape/article/details/80372743

    tips:
    如果安装过程出现报错,根据错误提示进行调整,比如报错urllib3之类的错误,可能是urllib3库中某些东西影响了安装,可以先卸载urllib3,安装成功后,再安装urllib3
    urllib3是使用requests库所依赖的,也需要安装的

    各excel库对比
    在这里插入图片描述
    Pandas扩展库
    安装:

    	pip install pandas
    

    简介:
    Pandas(Python Data Analysis Library)基于Numpy构建,让基于Numpy的应用更简单,被广泛应用于金融行业,流行的数据分析工具

    将多个dict转成list的合集

    import pandas as pd
    data = [
        {'A': 'A1','B': 'B2','C': 'C3','D': 'D4'},
        {'A': 'AA1','C': 'CC3','D': 'DD4','E': 'EE5'},
        {'A': 'AAA1','B': 'BBB2','C': 'CCC3','D': 'DDD4','E': 'EEE5'}
    ]
    df = pd.DataFrame(data).fillna('null')
    ls = df.values.tolist()
    ls.insert(0, df.columns.tolist())
    print(ls)
    

    pillow图片处理库
    PIL(Python Imaging Library)是Python一个强大方便的图像处理库,名气也比较大。不过只支持到Python 2.7。

    PIL官方网站:http://www.pythonware.com/products/pil/

    Pillow是PIL的一个派生分支,但如今已经发展成为比PIL本身更具活力的图像处理库。目前最新版本是3.0.0。

    Pillow的Github主页:https://github.com/python-pillow/Pillow

    Pillow的文档(对应版本v3.0.0):

    https://pillow.readthedocs.org/en/latest/handbook/index.html

    Pillow的文档中文翻译(对应版本v2.4.0):http://pillow-cn.readthedocs.org/en/latest/

    Python 3.x 安装Pillow

    给Python安装Pillow非常简单,使用pip或easy_install只要一行代码即可。

    在命令行使用PIP安装:

    pip install Pillow
    

    或在命令行使用easy_install安装:

    easy_install Pillow
    

    安装完成后,使用from PIL import Image就引用使用库了。比如:

    from PIL import Image
    im = Image.open("bride.jpg")
    im.rotate(45).show()
    

    阿里云oss接口

    一、OSS安装

    1、安装python-devel
    对于Windows和Mac OS X系统,由于安装Python的时候会将Python依赖的头文件一并安装,因此您无需安装python-devel。
    对于CentOS、RHEL、Fedora系统,请执行以下命令安装python-devel:

    yum install python-devel
    

    对于Debian,Ubuntu系统,请执行以下命令安装python-devel:

    apt-get install python-dev
    

    2、pip安装oss2
    使用pip安装即可,也可以参考下方官网安装:

    pip install oss2
    

    oss安装
    安装成功可以执行以下命令检测安装结果:

    >>> import oss2
    >>> oss2.__version__
    '2.5.0'
    

    3、python卸载oss2
    如果安装失败,建议通过pip卸载然后重装。卸载命令如下:

    pip uninstall oss2
    
    二、OSS的使用

    1、创建存储空间
    以下代码用于创建存储空间:

    # -*- coding: utf-8 -*-
    import oss2
    auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')
    # Endpoint以杭州为例,其它Region请按实际情况填写。yourBucketName就是你要创建的Bucket
    bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')
    bucket.create_bucket(oss2.models.BUCKET_ACL_PRIVATE)
    

    2、上传文件
    以下代码用于上传文件至OSS:

    # -*- coding: utf-8 -*-
    import oss2
    auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')
    # 如上描述
    bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')
    # <yourLocalFile>由本地文件路径加文件名包括后缀组成,例如/users/local/myfile.txt
    bucket.put_object_from_file('<yourObjectName>', '<yourLocalFile>')
    yourLocalFile由本地文件路径加文件名包括后缀组成,例如/users/local/myfile.txt
    yourObjectName是上传后的保存地址
    

    tips(多种上传文件方式):
    bucket.put_object(key, data, headers=None, progress_callback=None)
    上传一个普通文件。
    Bucket.put_object_from_file(key, filename, headers=None, progress_callback=None)
    上传一个本地文件到OSS的普通文件。
    Bucket.append_object(key, position, data, headers=None, progress_callback=None, init_crc=None)[source]
    追加上传一个文件。

    3、下载文件
    以下代码用于将指定的OSS文件下载到本地文件:

    # -*- coding: utf-8 -*-
    import oss2
    auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')
    bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')
    # <yourLocalFile>由本地文件路径加文件名包括后缀组成,例如/users/local/myfile.txt
    bucket.get_object_to_file('<yourObjectName>', '<yourLocalFile>')
    yourLocalFile是保存在本地哪个文件夹
    yourObjectName是线上文件地址
    

    4、列举文件即获取文件夹列表
    以下代码用于列举指定存储空间下的10个文件:

    # -*- coding: utf-8 -*-
    import oss2
    from itertools import islice
    auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')
    bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')
    # oss2.ObjectIteratorr用于遍历文件。
    for b in islice(oss2.ObjectIterator(bucket), 10):
        print(b.key)
    

    5、删除文件
    以下代码用于删除指定文件:

    # -*- coding: utf-8 -*-
    import oss2
    auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')
    bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')
    bucket.delete_object('<yourObjectName>')
    
    app分析

    首先使用fildder抓包工具+夜神安卓模拟器对app进行接口分析

    获取cookie的接口:
    在这里插入图片描述

    多线程加队列

    思路
    采用threading多线程+队列queue,首先把所有文章分类依次加入队列,也就是以单个分类为单位,目前使用dict保存分类单位。

    import threading   #多线程
    import queue    # 队列
    

    步骤
    1、请求到所有分类,加入队列,循环完毕后开启多线程

       for cat in cats_json:
            # 合并请求参数(该方法要求python3.5+)
            params = {**self.params, **self.cat_params}
            params[self.map['cat_param']] = cat[self.map['cat_id']]
            #添加到队列
            self.addQueue(self.list_url, params, cat)
          
        # 启动多线程
        self.handleWorkers(len(cats_json))
    

    2、多线程开启,每个线程依次从队列中获取任务并进行处理

    	# 多线程处理
    def handleWorkers(self, threadNum=1):
        # threadNum 可以调节线程数, 进而控制抓取速度
        #threadNum = 1
        # 当前时间
        startTime = time.time()
        # 线程列表
        threads = []
        for i in range(0, threadNum):
            # 创建一个线程
            t = threading.Thread(target=self.fetchUrl, args=(self.urlQueue,))
            threads.append(t)
        for t in threads:
            # 设置守护进程
            t.setDaemon(True)
            # 启动进程
            t.start()
        for t in threads:
            # 多线程多join的情况下,依次执行各线程的join方法, 这样可以确保主线程最后退出, 且各个线程间没有阻塞
            t.join()
        endTime = time.time()
        print('主线程结束, Time cost: %s ' % (endTime - startTime))
    

    3、具体的业务逻辑处理,值得注意的是线程锁的应用(threading.Lock() )

    多线程再完成一些共享资源的读写操作的时候往往会出现文件被锁定,数据错乱的问题,那么这时候需要使用threading.Lock() 来保证依次执行这些共享操作,比如文件的操作,使用锁可以避免多个线程同时使用该文件。
    具体用法有两种
    一种:

    	lock = threading.Lock() 
    	lock.acquire()
    	# 文件等操作
    	lock.release
    

    一种

    lock = threading.Lock() 
    with lock;
    	# 文件等操作
    	pass(pass可加可不加)
    

    一般会使用在循环中,确保循环中每次操作都是独立的,避免造成数据混乱

    附录

    html转义和反转义

    在爬网页的时候,有时候会返回一些转义的字符,比如,在抓取某个网站的时候,返回的内容是直接通过js输出到页面的,也就是说我们获取到的是通过js转义后的字符串,并且存在于script标签中

    document.writeln(unescape("%3Cp%20style%3D%22font-size%3A%
    

    这种形式无法直接获取数据,首先需要使用正则匹配中被转义的字符串,也就是unescape后面的字符串,最后还需要进行转义,转义的方法如下
    用 Python 来处理转义字符串有多种方式,而且 py2 和 py3 中处理方式不一样,在 python2 中,反转义串的模块是 HTMLParser。

    python2
    import HTMLParser

    HTMLParser().unescape(‘a=1&b=2’)
    ‘a=1&b=2’
    Python3 把 HTMLParser 模块迁移到 html.parser

    python3

    from html.parser import HTMLParser
    HTMLParser().unescape(‘a=1&b=2’)
    ‘a=1&b=2’
    到 python3.4 之后的版本,在 html 模块新增了 unescape 方法。

    python3.4

    import html
    html.unescape(‘a=1&b=2’)
    ‘a=1&b=2’
    推荐最后一种写法,因为 HTMLParser.unescape 方法在 Python3.4 就已经被废弃掉不推荐使用,意味着之后的版本有可能会被彻底移除。

    另外,sax 模块也有支持反转义的函数

    from xml.sax.saxutils import unescape
    unescape(‘a=1&b=2’)
    ‘a=1&b=2’

    以上的解码操作主要是处理html转义字符,也就是html对&,<>等符号的转义后的反转义处理

    使用以上方法解码js中escape编码处理过的字符串,发现都达不到效果,也就是没有生效,
    于是根据代码中存在%3C等编码字符,所以使用urldecode方式进行解码,具体如下:

    from urllib import parse
    url_data = parse.unquote(str)   //解码以后会把特殊的符号<,/&等还原,最后得到
    <p style="text-align: center;"><strong><span style="font-size: 20px;">%u8bf4%u5230%u5c0f%u6c88%u9633%uff0c%u4ed6%u6700%u8fd1%u51e0%u5e74</span></strong></p>
    

    此时发现虽然标签还原了,但是标签的内容还是编码字符,观察编码发现所有的都是由%u和四位数字+字母组成,其实这就是js escape编码,每个汉字都是“%u”符号加4位字符编码
    所以通过分析,我们发现js中escape编码是%u,而python3使用urillib进行编码是%u变为%5Cu
    因此只需要在输出时,再进行一次替换即可

    python 编码
    #编码
    import urllib
    print(urllib.parse.quote('你好哈<as>'.encode('unicode-escape')).replace('%5Cu', '%u'))
    
    %u4f60%u597d%u54c8%3Cas%3E
    
    python 解码

    escape则不是将%u替换为%5Cu来处理,而是%u替换为\u,进行处理,相当于json字段处理过程

    #escape 解码
    import urllib
    st ="%u4F60%u597D%3Cas%3E".replace('%u', '\\u')
    print(st)
    k =urllib.parse.unquote(st.encode().decode('unicode-escape'))
    # 这里的unqoute方法主要是解码一些特殊字符的编码,比如<,/>等等,一般是html标签
    print(k)
    
    \u4F60\u597D%3Cas%3E
    你好<as>
    

    或者可以使用json库来解码

    import json
    s ="%u4F60%u597D%3Cas%3E"
     jsonObj = '"' + "".join([(i and "\\" + i) for i in s.split('%')]) + '"'
     print(json.loads(jsonObj))
    你好<as>
    

    注意:这里的unquote方法可以解码%3Cp%20这种编码,类似于php的urlencode编码。st.encode().decode(‘unicode-escape’)这里是对经过js的escape编码后的字符串进行%u替换为\u后的字符进行解码成中文的处理
    通过这两步处理,就可以处理经过js escape编码后的字符,核心在于将%u替换\u的步骤,否则将无法解码成功

    BUG总结

    保存webp格式图片报错

    报错内容:OSError(‘cannot write mode RGBA as JPEG’)
    原因 使用PIL(python3安装Pillow库,python2安装PIL库)的image的对象处理图片时保存为RGB类型的jpg格式
    解析 需要丢弃Alpha频道或保存为支持透明度的东西 - 比如PNG。
    该image-class有一个方法convert可以用来转换RGBA到RBG-之后,你就可以使用JPG。

    im = Image.open("audacious.png")
    rgb_im = im.convert('RGB')
    rgb_im.save('audacious.jpg')
    

    或者保存支持透明度的png也可以

    rgb_im.save('audacious.jpg','PNG')
    
    展开全文
  • 数据转移工具

    2018-10-29 13:19:35
    适合运维人员使用 希望帮助到你 帮助你解决问题
  • 用于将 RDF 数据迁移到 Neo4j 图数据库的迁移实用程序 先决条件: Java 1.7 或更高版本 阿帕奇Maven 一个启动并运行的 Neo4j 图数据库实例 如何构建: 此实用程序使用 Apache Maven。 因此,只需下载/克隆存...
  • 相对应的金融科技也在不断的更新和迭代,每次有新的软件系统出炉的时候,就是老的软件系统命运终结的开始,老的项目当然不会束手就擒,它也会做最后的挣扎,当你从它身上迁移用户或者商户的时候,它会给你带来很多...

    互联网金融行业发生了翻天覆地的变化,相对应的金融科技也在不断的更新和迭代,每次有新的软件系统出炉的时候,就是老的软件系统命运终结的开始,老的项目当然不会束手就擒,它也会做最后的挣扎,当你从它身上迁移用户或者商户的时候,它会给你带来很多麻烦,比如说,它会临时罢工、出现资金损失等等不可忽视的问题,因此,迁移是个大任务,有的时候迁移并不亚于开发一套新系统的难度,甚至可以说是有过之而无不及。

     

    哪些场景需要迁移

    我们总结了各种需要迁移的场景。

    字段迁移

    原来设计的字段大小不能满足现在业务的需求,直接在原表上扩容字段可能会影响线上跑的业务,因此,我们需要增加一个字段来替换原来的字段;字段的数据格式需要升级,通过新增字段来替换原有字段,例如:原有未加密的字段处于安全需求进行加密。

    表迁移

    用于数据库表设计重构的场景,原有表的结构不合理,新增合理的表来替换原有的表,这时候我们需要表迁移。

    数据库迁移

    把单库迁移到分库分表的多个库;从一种数据库迁移到另外一种数据库;分库分表的多个库需要扩容的时候,需要进行数据库迁移,迁移到一套能够容纳足够数据的数据库集群。

    数据库迁移到其他类型的库

    对数据库的选型发生了变化,例如:微博的粉丝库从原有的 MySQL 迁移到 HBase。

    系统迁移

    原有系统的技术已经过时了,不能满足新需求或者业务发展的需要,开发完成新系统来替换原有系统。

    通用的迁移方法论

    通用的迁移方法分为平滑迁移和停机迁移,平滑迁移一般采用双写的方案,不需要停机就可以完成迁移,类似飞机的空中加油,或者给运行的汽车换轮子。而停机迁移,则需要停止现有的业务服务,然后迁移数据,待数据迁移之后,再开启对外提供服务。

    这里讲解的方法论是一种通用的迁移方案,既适合字段迁移、表迁移,也适合库迁移以及应用迁移,既适合数据库的迁移也适合缓存的迁移,虽然在细节上有些不同,但是在方法论上则大同小异,我们以分片后的数据容量不能满足需求,需要对分片后的数据扩容为例,这里的扩容实际上是迁移的一种特殊案例,我们以扩容为例来说明相应的步骤和实现细节。

    平滑迁移

    平滑迁移适合对可用性要求较高的场景,例如,线上的交易服务对缓存或者数据库依赖较大,不能忍受停机带来的业务损失,也没有交易的低峰期,我们对此只能采用平滑迁移的方式。

    平滑迁移,是指将正在提供线上服务的数据,从一个地方数据存储到另一个数据存储,整个迁移过程中要求不停机,服务不受影响。根据数据所处层次,可以分为缓存迁移、数据库存储迁移、应用迁移等等;根据数据迁移前后的变化,又可以分为数据平移和数据转移。数据库对数据库的迁移属于平移,数据库对其他 NoSQL 库的迁移属于数据转移。

    数据平移是指迁移前后数据组织形式不变,比如 MySQL 数据库从1个实例扩展为4个实例,Redis 缓存从2个实例扩展到8个实例等等。

    如果在最初的设计里就为以后的扩容做好准备,也就是做了充分的容量评估(关于容量评估,请参考《分布式服务架构:原理、设计与实战》一书中第3章的内容),那么数据迁移工作就会简单很多,比如 MySQL 已经做了分库分表,扩展实例的时候,只需要多做几个从库,切换访问关系,最后将冗余的库表删除即可达到扩容的效果,当然,这需要短暂的停止服务。

    近年来出现很多支持自动可伸缩的数据库,在实现上已经做到全自动数据迁移,如 HBase、TiDB 等,那就更简单了,只要通过管理功能来添加机器,手工修改配置或者系统自动发现,就可完成数据库容,也就免去了复杂的数据迁移等工作。

    数据转移是指在数据迁移前后,数据组织形式发生了变化。比如将 MySQL 数据库迁移到 HBase 数据库,微博就经历过这样的过程。

    平滑迁移通常使用的是双写方案,方案分成4个步骤:双写、迁移历史数据、切读、下双写。

    这种方式如果应用于缓存扩容的迁移场景,则还有一个变种,就是不需要迁移旧数据,在第1步中双写后,在一定的时间里通过新规则对新缓存进行写入,新缓存已经有了足够的数据,这样我们就不用再迁移旧数据,直接进入第3步即可。

    首先,假设我们的应用现在使用了具有两个分片的数据集群,通过关键字哈希的方式进行路由,如下图所示。

    因为两个分片已经不能满足容量的需求,所以现在需要扩容到4个分片,达到原来两倍的总大小,因此我们需要迁移。

    迁移的具体过程如下。

    (1)双写

    按照新规则和旧规则同时往新旧数据系统中写数据,如下图所示。

    这里,我们仍然按照旧的规则,也就是关键字哈希除以2取余来路由分片,同时按照新的规则,也就是关键字哈希除以4取余来路由到新的4个分片上,来完成数据的双写。

    这个步骤有优化的空间,因为是在成倍扩容,其实,我们不需要准备4个全新的分片,对于新规则中的前两个分片的数据,其实是旧规则中的两个分片数据的子集,并且规则一致,所以我们可以重用前两个分片,也就是一共需要两个新的分片,用来处理关键字哈希取余后为2和3的情况,使用旧的数据分片来处理关键字哈希取余后0和1的情况即可。如下图所示。

    (2)迁移历史数据

    把旧缓存集群中的历史数据读取出来,按照新的规则写到新的数据集群中,如下图所示。

    在这个过程中,我们需要迁移历史数据,在迁移的过程中可能需要迁移工具,这也需要一部分开发工作量。在迁移后,我们还需要对迁移的数据进行验证,表明我们的数据迁移成功。

    在某些应用场景下,例如缓存数据,并不是应用强依赖的,在缓存里获取不到数据,可以回源到数据库获取,因此在这种场景下通过容量评估,数据库可以承受回源导致的压力增加,就可以避免迁移旧数据。

    在另一种场景下,数据一般是具有时效性的,应用在双写期间不断向新的集群中写入新数据,历史数据会逐渐过时,并被从旧的集群中删除,在一定的时间流逝后,新的集群中自然就有了最新的数据,就不再需要迁移历史数据了,但是这需要进行评估和验证。

    (3)切读

    把应用层所有的读操作路由到新的数据集群上,如下图所示。

    在这一步骤里,把应用中读取的操作的数据源转换成新的数据集群,这时应用的读写操作已经完全发生在新的数据库集群上了。这一步一般不需要上线代码,我们会在一开始上双写时就实现开关逻辑,这里只需要将读的开关切换到新的集群即可。

    (4)下线双写

    在这一步,我们把写入旧的集群的逻辑下线,如下图所示。

    这一步通常是在双写和切读后验证没有任何问题,并保证数据一致性的情况下,才把这部分代码下线。同时可以把旧的分片下线,如果是扩容的场景,并且重用了旧的分片1和分片2,则还可以清理分片1和分片2中的冗余数据。

    对于字段迁移来讲,我们除了新增字段,双写后替换原来字段,我们还可以采用原地替换的方法,对于新数据加密,加密后做标志,然后异步的将历史数据加密,让查询程序兼容加密的数据和非加密的数据。

    可以用“软着陆”来形容双写迁移方案,这和新领导上任后,一般先招心腹,慢慢的替代老下属的职责,慢慢淘汰老下属,慢慢实现软着陆如出一辙。

    停机迁移

    停机迁移的方法比较简单,通常分为停止应用、迁移旧数据、更改数据源文件、启动应用这4个步骤,如下图所示。

    具体的迁移步骤如下。

    1. 停机应用,先将应用停止服务。

    2. 迁移历史数据,按照新的规则把历史数据迁移到新的缓存集群中。

    3. 更改应用配置,指向新的缓存集群。

    4. 重新启动应用。

    这种方式的好处是实现比较简单、高效,能够有效避免数据的不一致,但是需要由业务方评估影响,一般在晚上交易量比较小或者非核心服务的场景下比较适用。

    如何验证迁移成功?

    迁移过程中最重要的一环就是如何验证迁移方案是成功的,我曾经给小伙伴们定了一个顺口溜。

    要明确什么样角色的什么人在什么时候到什么系统看到什么样的数据,才能确认迁移成功。

    虽然这是看似简单的一句话,但是信息量满满的,有了这句话作为指导,能够确保迁移方案的方向一定是正确的,一定不会导致太大的问题。

    这句话具体包括几个要素:谁、什么时候、什么样的数据,这些必须在迁移方案中都要事先明确,具体执行的人必须了解清楚这些条款,假设我们在迁移支付行业中的计费模板,那么迁移切量后,我们就需要计费的运营在切量后的第一时间到计费系统中查看计费的准确性,并且明确什么样的计费结果是准确的,什么样的计费结果是不准确的。

    有的时候只靠人来确定数据是否正确恐怕还不够,我们通常需要工具自动化的进行比对,同样我们以计费模板迁移为例,我们从一套计费模板迁移到另外一套计费模板中,通常在初期我们不会真正的以新模板为准,我们会在程序中实现“双计”,既使用老的计费模板计费,也使用新的计费模板计费,在初期我们以老的计费模板为准,新的计费模板计费的结果只用于比对,并且计入日志,这样通过程序自动比对一段时间以后,发现新的计费模板确实没有问题,我们才真的开启开关,以新的计费模板为准。

    当然,有的时候数据量巨大,我们比对每一个流量产生的数据不太现实,也会严重影响性能,这个时候我们需要对数据比对进行抽样,只对一些比较有代表性的数据进行比对。

    系统迁移后数据清洗?

    系统迁移过程中,上了双写以后,历史数据仍然保留在老系统,因此,我们需要将历史数据迁移到新系统,因为,有些时候我们需要读取或者修改历史数据,例如支付行业的退款等。

    我们把迁移历史数据的过程称为洗数据,通常使用如下的步骤来实现。

    1. 先清洗历史数据,将清洗后的数据写入新系统。

    2. 做全量对比,如果数据太多,没法全量对比,就抽样对比,看看有没有不一致的数据。

    3. 在数据量巨大的情况下,线上系统复杂,出现少量的不一致是正常的,这时候不一致的数据进行分析,这时候可能需要参考线上服务系统的交易日志,查明造成不一致的原因,并进行修复。

    这里,有读者会对上面第2步有疑问,为什么会产生不一致的数据呢,这有很多原因。下面我们来仔细分析。

    对于增加记录,到迁移历史数据这一阶段,我们使用的是双写,因此,数据在新老数据库中都会存在,即使双写有问题,导致一方不存在,我们也可以通过比对来补齐。

    对于更新数据,则容易产生不一致,导致新老数据库的数据不一致,假设在迁移某条历史数据的过程中,线上的交易系统正好修改了这条数据,在双写系统还没有更新历史数据的时候,迁移工具已经把这条数据拿到了应用系统中,这时数据在新老库中都更新了,但是迁移工具后续又把老版本的这条数据更新到新系统中,就导致数据不一致。

    对于删除数据,和上面更新数据有一样的问题,也会导致不一致的问题,这时候以谁为准,怎么保证一致性是个难题,我们需要借助修改的 timestamp 或者版本来区分哪一个是最新的版本,然后对数据进行修复。还有另外一个更好的方法,对于某些业务,数据是有一定时效性的,超过一定时间的数据就不再更改,因此,我们可以让双写的时间拉长,要长于数据更新的时间段,这样在历史数据完全不被更新的时候,我们再进行洗数据,就不会因为迁移而产生不一致了。

    迁移失败怎么办?

    这里探讨,迁移失败了,迁移后验证迁移有问题了,怎么办?其实,迁移失败了没有什么好的办法,只有两个途径可以走,一个就是迁移失败了就在新系统中修复,但是有些时候这可能会导致更多不可用时间,另外一个方案就是迁移失败了,需要迁移回来,但是迁移回来迁移过程中产生的数据怎么办?

    这是唯一能用的两个办法,没有更好的办法能解决迁移失败的问题,因此,在这个问题上我们不能奢求完美的解决方案,我们只能退而求其次,提前做好应对方案。

    如果我们决定了迁移失败了就在新系统中修复,而不再切回老的系统,我们就要充分的做好应急方案,一旦这种事情出现了,我们要预测可能产生的问题,针对问题做相应的解决方案,甚至我们提前做好工具,在问题出现的时候,我们要快速发现和快速恢复。

    如果我们决定了迁移失败后要迁移回来老系统,我们也要提前做好应急方案,应急方案中要包含如何发现问题,如何迁移回老系统,将流量迁移回老系统之后,还要考虑在新系统中遗留的数据怎么办,通常来讲,我们有两个方法,一种方法是通过工具把这些数据迁移回老系统,另外一种方法是让老系统兼容新数据。

    迁移方案的评审?

    这里我们详细阐述作为架构师应该如何评审迁移方案。

    首先,需要有人牵头写即将要评审的迁移方案,迁移方案的内容要包括具体的迁移产品,迁移的目的是什么,描述为什么要进行此次迁移,以及要达到什么效果,迁移任务的时间点,迁移方案什么时候在系统上实施,什么时候真正的进行切量,什么时候进行验证,什么时候结束,迁移过程中有什么原则,迁移会影响多少用户和商户,影响到什么程度,这次迁移的主要负责人是谁,参与人是谁,这些都需要落实到纸质的文档。

    然后,我们最需要考虑的就是这次迁移的影响范围,都对哪些角色的人会产生影响,以及对哪些人是透明的,这要评估是否对商户、用户、运营人员等有感知,如果对任何人有感知,需要制定提前通知的方案,要通知哪些人,什么时候通知,以什么形式通知,是否需要被通知人回复认可等。

    接下来需要确认迁移用户和商户的选择、顺序、批次,一般选择不重要的用户和商户先迁移,验证迁移过程没问题,再迁移重要的用户和商户,要综合考虑用户和商户的等级、交易类型、迁移复杂度等,以此确定用户和商户迁移顺序和批次。

    通常,在全量切换之前,我们需要进行多次验证,我们需要在准生产测试迁移变更逻辑和开关逻辑,或者通过 TCPCopy 环境来验证代码变更的正确性,然后,通过少量的内部用户在线上验证逻辑的正确性,最后,会按照我们选定的用户和商户的批量,逐渐的放量、观察和验证,最后再全量切换。

    然后,要确定迁移过程中对系统的变更内容,要确定变更的关键内容,然后做测试方案,要测试到所有的场景,包括迁移开关的开和关,要测试迁移失败后迁移回老系统的情况,不要抱着侥幸态度就忽略这部分的测试。

    最后,进入迁移方案的关键内容,要对迁移的过程识别风险,这包括交易风险、业务风险、系统风险、技术风险和政策风向等,要对迁移过程中更改的信息流和资金流进行详细评估,对识别的风险要给出应对方案。

    迁移开关和迁移工具

    在迁移的过程中,除了要配合迁移开发系统,还有两个比较特殊的工作。

    一个就是迁移开关的设计,在迁移的过程中,双写、切流量、有问题了切回流量,这些都需要使用迁移开关,迁移开关的设计非常的重要,如果迁移开关设计的不合理会产生很大问题,甚至会导致资金损失,在我经历过的金融系统中,曾经经历过迁移开关设计在统一的共享缓存上,由于网络原因重试导致请求流量重复,请求流量走到了不同的应用节点上,不同应用节点读取共享缓存有时差,导致两个流量一个走了开的逻辑,一个走了关的逻辑,如果后端系统没有做幂等,这会导致资金损失。因此,我们对迁移开关的设计,制定了如下的最佳实践。

    1. 迁移开关要做在订单上,在订单上标记是否迁移新系统。

    2. 迁移开关要有不同的维度,可在订单上,可在商户或者用户上,可在系统级别。

    3. 迁移开关要能开能关,也就是流量要能切到新系统,也要能切到老系统。

    另外一个重要的任务是开发迁移工具,比如说迁移后校验数据,对比数据等,这都需要开发专业的工具,靠运营对比大量的数据很容易产生误差,如果想做好迁移,就要舍得成本来投入到这些关键任务上。

    迁移过程中的政治因素

    迁移是个费力不讨好的工作,因此,很多人其实不愿意干这个活,迁移做得好,那是应该做的事情,迁移出现了问题,那全是工作没做好,况且迁移总不会顺顺利利的,这就是为什么大家不愿意做,越是有挑战的任务,其实,它的内在价值就越大。

    但是要真的想做一次彻底的迁移,替换掉老的系统,这需要一定的激励措施,要与迁移负责人和参与人明确迁移的目标和价值,一旦按照计划迁移成功除了迁移过程中给大家带来的经验,还有什么样的奖励,否则,只是作为一个常规任务,那么参与者必然失去兴趣,迁移也就成了挠痒痒,基本就变成今天迁移一点流量,明天迁移一点流量,最后就新老系统并存,不伦不类的。

    迁移一定要由架构组来把关

    数据迁移并不是一项需要高大上的技术工作,它需要的是对业务逻辑的把控,对操作流程的理解,对新旧系统特性和环境的掌握,以及对细节的掌控,要深入骨髓般的理解系统才能做好,因此迁移是需要架构组来把关的。

    但是,迁移的事情也不是那么简单的,也不能由运营单独搞定的,这涉及到迁移工具的开发,迁移后的验证,迁移失败如何迁回,脏数据如何处理,迁移过程中如何平滑过度,例如迁移计费模板的过程,应该开发工具进行对比结果后,才能真正的使用新的计费系统,这些都是必须有业务人员和技术人员来共同完成的,因此,迁移工作最好由架构组牵头,由产品、运营、技术等一起来实施。

    如何汇报迁移技术方案

    由于迁移是个非常大的任务,设计的部门和角色比较多,由于出了问题产生的影响比较大,因此,很多老板都会关注迁移的方案,这里,对于迁移负责人和架构师,要负责给不同角色的人汇报迁移方案,这里我总结的一个最佳实践是不同角色的人关注不同的内容。

    1. 销售的老板会关注迁移后带来的价值,带来哪些系统能力的提升,能够带来多少毛利的增长。

    2. 业务的老板关注的是业务的风险,关注迁移以后是否带来产品能力的提升等等。也会关注成本的降低;还会关注迁移的里程碑,时间点等。

    3. 运营的老板更会关注迁移的实施方案,包括如何通知商户、如何选择商户等。

    4. 而技术的老板会关注具体的迁移设计方案本身。

    因此,在给不同的老板做汇报的时候,我们汇报内容的侧重点要有所不同。

    展开全文
  • 有一段时间没看python今天删除数据库重新建立迁移的时候 python manage.py makemigrations python manage.py migrate 发现死活不能创建app中自己写的模型,原因很简单我之前在git提交代码的时候把migrations这个...

    有一段时间没看python今天删除数据库重新建立迁移的时候

    python manage.py makemigrations
    python manage.py migrate

    发现死活不能创建app中自己写的模型,原因很简单我之前在git提交代码的时候把migrations这个包删了,不要在删除这个包官方也是不推荐的,重新在你的app目录下建立migrations这个文件夹,文件夹下记得有_init_.py


    这里是附上强制重置数据迁移的方法:
    传送门

    展开全文
  • 重装系统前要先备份原系统里的数据资料,那我们要顺道将需要迁移的软件(App)相关文件备份下来,如果原系统进不去了,里面的文件拷贝不出来了,请参见这篇文章《 Mac OS系统进不去,重装也不行,只能抹盘安装,如何...
  • 陈宏斌 2019-6-3高级软件工程师概要随着手机图片、音乐、视频以及其他数据逐渐添加,原本手机及SD卡的内存可能已经不满足我们的数据存储...在SD卡里没有隐藏或锁定文件的情况下,并且要迁移数据文件少,我们或许...
  • 数据迁移 ...此命令将在app/DataMigrations/PermissionDataMigration.php生成数据迁移数据迁移将包含model , data和options方法。 <?php namespace App \ DataMigrations ; use Fndmiranda \
  • 超详细的APP数据指标体系分析

    万次阅读 多人点赞 2019-07-16 23:20:38
    一、为什么要做APP数据分析 1.搭建数据运营分析框架 一个APP的构建与运营工作通常由多个角色分工实现,由于大家的工作重点不同,仅关注一个方面的数据就如同管中窥豹,无法全面了解产品运营情况,不能提出行之有效的...
  • 手账产品从实物到APP应用的元素迁移研究.pdf
  • 在django中创建了一个app,而且在app中自定义创建了几个数据表,在同步的时候系统自带的表可以成功,但是models中的没有生效,而且进入对应app下的migrations目录,发现为空,应该如何解决呢! 解决方式: python3 ...
  • 1.App迁移需要苹果审核吗? 答:不需要 2.App迁移需要多长时间? 答:迁移操作过程很快,A账号发出申请,B账号接收,几分钟时间。App Store 展示B账号相关信息可能几分钟,也可能有延迟几个小时,无需担心。 ...
  •  因刚开始安装mysql的时候没有考虑后期磁盘分区空间问题,所以mysql的数据保存目录按安装默认的目录/usr/local/mysql/(我下载的是一个lamp一键安装包安装的mysql),现在随着服务的运行发现/usr/local/mysql所在...
  • 现在我的App.vue里面有一个头部的公共组件,头部组件里有一个输入框,当我输入词条时,将词条传进App.vue里的里的.vue页面,并进行查询获取数据 解决思路如下: 1.如何拿到头部的词条 2.当词条改变时如何触发.vue里...
  • ▲该文要义,主要是介绍HDD迁移和Hyper Backup 迁移两种方法《能用哪种工具来复制我的 Synology NAS 数据》综合上面几篇KB文章介绍,初步确定了5种数据迁移方法 1. HDD迁移+增换 (1)将1515+上5块硬盘按照...
  • 首先数据库迁移的两大命令: python manage.py makemigrations & python manage.py migrate 前者是将model层转为迁移文件migration,后者将新版本的迁移文件执行,更新数据库。 这两中命令调用默认为全局,即对...
  • Django修改app名称和数据迁移方案

    千次阅读 2020-02-17 16:44:28
    我的博客由两个app组成,Blog和JiaBlog,总觉得不美观,想改成小写的oblog和blog,那么最关键的地方在于和orm数据表的映射 把JiaBlog.articles改成blog.articles是终极目标,这里不推荐用django的migrate 写一个...
  • Spark sql 数据迁移

    千次阅读 2018-04-12 22:05:40
    数据迁移当然可以使用sqoop,但是我使用的时候发现配置不当有很多错误,使用起来很麻烦,于是自己就用了最原始的方法来迁移数据,熟练步骤了其实也很快,给大家一个参考一、迁移一张表查看表结构:desc table tb1;...
  • Mac电脑里储存的大量文件资料习惯使用的系统设置、帐户信息,都能通过 Mac 自带的迁移助理 app,事无巨细地转移到新 Mac 上。 需要准备什么? 将两台 Mac更新至最新系统版本。 两台电脑靠近放置并打开 Wi-Fi。 在...
  • 迁移常见错误解决方案 django官网迁移教程 执行启动迁移 DJANGO_ENV='test' python manage.py makemigrations --settings=iCrawler.settings_test main # main 为应用名 DJANGO_ENV='test' 为设置环境变量 执行...
  • 移动客户端数据分析报告;移动客户端总体情况描述;活跃用户;活跃用户地区分布;活跃时段分布;页面访问;用户转化情况;实名认证充值转化;...PC/WAPAPP迁移率分析;PC/WAPAPP迁移率分析;PC/WAPAPP迁移率分析;总结
  • iOS-App版本升级时数据库的迁移更新

    千次阅读 2016-12-21 15:56:55
    ,当用户第一次下载安装app的时候,第一次建立版本库,将我们的数据信息存入数据库中,同时保存一个当前版本号加一的字段到数据库中. 那么问题来了,为什么我们需要将版本信息加一呢,这是为了以后进行版本判断的时候...
  • hadoop 数据迁移

    千次阅读 2018-11-18 13:19:36
    数据迁移使用场景 冷热集群数据分类存储,详见上述描述. 集群数据整体搬迁.当公司的业务迅速的发展,导致当前的服务器数量资源出现临时紧张的时候,为了更高效的利用资源,会将原A机房数据整体迁移到B机房的,原因可能是...
  • 使用Trucker将旧数据迁移到您的Rails应用中。 安装 安装卡车司机的宝石 sudo gem install trucker 将trucker添加到environment.rb的config.gem块中。 config . gem "trucker" 生成基本卡车司机文件 script/...
  • uni-app代码迁移

    千次阅读 2019-03-29 16:54:21
    小程序代码迁移uni-app之注意事项 1.如果项目中有px单位并且使用style动态绑定的最好在masinfest.json中配置 “transformPx”: false,否则uni-app会将px转换为自适应单位, 2.尽量使用class动态绑定类名代替动态绑定...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 69,290
精华内容 27,716
关键字:

怎么迁移app的数据