zoukankan      html  css  js  c++  java
  • 撸了个 django 数据迁移工具 django-supertube

    撸了个 django 数据迁移工具 django-supertube

    支持字段映射和动态字段转化。 欢迎 star,issue
    https://github.com/FingerLiu/django-supertube

    起因

    最近参与了公司系统的重构,重构基本完成后,由于数据库表结构变化很大,很多小组都需要数据迁移。如果都写 sql 的话,要做很多重复的工作。于是去搜了下 django 有没有相关的工具,很遗憾没有搜到,于是自己撸了这个数据迁移的轮子。

    主要功能

    A powerful django migration tool to migrate from latency database to new databse using awesome django ORM
    使用 django 强大的 ORM 系统灵活的进行数据迁移工作。

    目前包含以下功能点:

    • 支持相同字段自动映射
    • 批量写入
    • 支持修改字段映射
    • 支持通过调用函数的方式
    • 自动修复 postgres sequence
    • 实时进度提醒
    • 数据量大时支持并行执行(开发中)

    django-supertube

    A powerful django migration tool to migrate from latency database to new databse using awesome django ORM

    例子

    settings.py

    DATABASES = {
        'default': config('DATABASE_URL', cast=db_url),
        'latency': config('LATENCY_DATABASE_URL', cast=db_url)
    }
    
    

    management/commands/mig_01_user.py

    from django.utils import timezone
    from si.tools.supertube import SuperTube, TubeSet
    """
    class LatencyUser:
        email
        password
        age
    
    class User:
        email
        age
        username
        password
        is_admin
        create_datetime
    
    例子从 latency 数据库的 LatencyUser 取数据迁移到 default 数据库的 User 中:
      - 新加 username 字段,数据值从原 email 字段取
      - 修改 age 字段变为原来的 age+1
      - 新加 create_datetime 字段
      - 新加 is_admin 字段,默认值为 False
    
    """
    class Command(BaseCommand):
        def handle(self, *args, **options):
            kwargs = {
                'mapping': {
                    'username': 'email',
                    'age': lambda obj: obj.age + 1, 
                    'create_datetime': timezone.now()},
                'defaults': {'is_admin': False}
                'source_db': 'whistler'
            }
            st = SuperTube(LatencyUser, User, **kwargs)
            st.run(stop_on_error=True)
    

    迁移工具 SuperTube 和 TubeSet 更多说明和例子参考这个文档

    一个为 latency 中的旧数据建表的例子:

    
    
    class Order(models.Model):
        sn = models.CharField(u'领用单编号', max_length=100)
        created = models.DateTimeField(u'创建时间', auto_now_add=True)
        apply_qty = models.IntegerField(u'计划领用数量', blank=True, null=True)
        # TODO 1 将原 model 中的外键字段名改为 原字段名+_id ,类型改为 IntegerField
        # batch = models.ForeignKey('stock.Batch', blank=True, null=True)
        batch_id = models.IntegerField('stock.Batch', blank=True, null=True)
        purpose = models.PositiveIntegerField(u'领用用途', choices=PURPOSES, blank=True, null=True)
        # platform = models.ForeignKey('si.Platform', blank=True, null=True, related_name='+')
        platform_id = models.IntegerField('si.Platform', blank=True, null=True)
    
        def __unicode__(self):
            return self.sn
    
        class Meta:
            verbose_name = u'Order'
            # TODO 2 注释掉原表中的 unique_together
            # unique_together = (
            #     ('platform', 'request_id'),
            #     ('platform', 'outer_id'),
            # )
    
            # TODO 3 managed 设为 False
            managed = False
            # TODO 4 指定 db table
            db_table = 'cardbox_applyvoucher'
    
  • 相关阅读:
    Go语言基础之结构体练习
    多对多表操作
    一对多表操作
    单表操作
    flask中orm增删改查操作
    基于scoped_session实现线程安全
    SQLAlchemy
    wtforms 表单使用
    记一次攻防演练复盘之计中计
    【漏洞复现】CVE-2021-22205 GitLab 未授权RCE
  • 原文地址:https://www.cnblogs.com/s0-0s/p/9373575.html
Copyright © 2011-2022 走看看