首页 文章 精选 留言 我的

精选列表

搜索[读写分离],共10000篇文章
优秀的个人博客,低调大师

Django前后端分离实践之DRF--03

一、序列化 1. 创建表 以出版社的表为例子,例如出版社有名字和所属地区 选区_051 class Publisher(models.Model): name = models.CharField(max_length=32, verbose_name='名称', unique=True) address = models.CharField(max_length=128, verbose_name='地址') def __str__(self): return self.name class Meta: verbose_name = '出版社' verbose_name_plural = verbose_name 选区_162 2. 生成迁移文件和执行迁移 在这里我们暂时用sqlite数据库 python manage.py makemigrations python manage.py migrate 3. 什么是序列化 维基百科资料关于序列化的介绍 3.1 关于序列化的解释: 在程序运行的过程中,所有的变量都是在内存中,比如,定义一个dict: d = dict(name='Zhangsan', age=26, score=75) 可以随时修改变量,比如把name改成'LiSi',但是一旦程序结束,变量所占用的内存就被操作系统全部回收。如果没有把修改后的'LiSi'存储到磁盘上,下次重新运行程序,变量又被初始化为'Zhangsan'。 <b style='color:red'>我们把变量从内存中变成可存储或传输的过程称之为序列化</b>,在Python中叫pickling,在其他语言中也被称之为serialization,marshalling,flattening等等,都是一个意思。 序列化之后,就可以把序列化后的内容写入磁盘,或者通过网络传输到别的机器上。 反过来,<b style='color:red'>把变量内容从序列化的对象重新读到内存里称之为反序列化</b>,即unpickling。 3.2 JSON <b style='color:red'>如果我们要在不同的编程语言之间传递对象,就必须把对象序列化为标准格式</b>,比如XML,但更好的方法是序列化为JSON,因为JSON表示出来就是一个字符串,可以被所有语言读取,也可以方便地存储到磁盘或者通过网络传输。JSON不仅是标准格式,并且比XML更快,而且可以直接在Web页面中读取,非常方便。 JSON表示的对象就是标准的JavaScript语言的对象,JSON和Python内置的数据类型对应如下: JSON类型 Python类型 {} dict [] list "string" str 1234.56 int或float true/false True/False null None Python内置的json模块提供了非常完善的Python对象到JSON格式的转换: 3.3 把Python对象变成一个JSON: import json d = dict(name='Zhangsan', age=26, score=75) # dumps()方法返回一个str,内容就是标准的JSON json_str= json.dumps(d) 3.4 要把JSON反序列化为Python对象,用loads()方法: json_str = '{"age": 26, "score": 75, "name": "Zhangsan"}' json.loads(json_str) 4. 通过以下方式可以实现API: 编写视图: from .models import Publisher from django.http import HttpResponse def publisher_list(request): # 查询出所有的出版社 queryset = Publisher.objects.all() # 转换成python中的列表 data = [] for i in queryset: # 每一个对象都手动转化成一个字典 p_tmp = { 'name': i.name, 'address': i.address } data.append(p_tmp) import json return HttpResponse(json.dumps(data), content_type='application/json') 选区_163 配置路由: url(r'^publishers/', views.publisher_list) 启动项目 python manage.py runserver 选区_164 手动添加数据 选区_165 刷新浏览器 选区_166 选区_167 5. 对于以上的方案进行第一次改进: data = [] from django.forms.models import model_to_dict for i in queryset: data.append(model_to_dict(i)) 注意:这种方式有缺陷,很多字段无法转换成字典,比如图片 选区_168 6. 对于以上的方案进行第二次改进(使用Django自带的serializers): data = [] from django.core import serializers data = serializers.serialize('json', queryset) import json return HttpResponse(data, content_type='application/json') 注意:此时data已经是json类型 选区_169 刷新浏览器 选区_170 二、DRF提供的序列化 DRF提供的方案更加先进,更高级别的序列化方案,不仅仅可以实现从数据库里面读取数据,更可以存数据(增删改查) 1. 在APP下创建一个序列化一个文件 我们自己定义一个序列化 from rest_framework import serializers # 类名固定为表名称 + Serializer class PublisherSerializer(serializers.Serializer): # read_only必须为True,因为我们模型里面的id是一个自增字段,不可写,自动生成 id = serializers.IntegerField(read_only=True) name = serializers.CharField(max_length=32) address = serializers.CharField(max_length=128) 选区_171 2. 使用自己定义的序列化 非常方便的把我们的对象转化成一个字典 from app01 import models,serializers p1 = models.Publisher.objects.first()# 先找到一个出版社的对象 s = serializers.PublisherSerializer(p1) s.data 选区_172 3. 给自定义的序列化增加一个'create'和'update'的功能 重写父类 def create(self, validated_data): # validated_data参数不需要特意去记,就是经过校验的数据 return models.Publisher.objects.create(**validated_data) def update(self, instance, validated_data): instance.name = validated_data.get('name', instance.name) instance.address = validated_data.get('address', instance.address) instance.save() return instance 使用 from app01 import models,serializers p2 = {'name':'图灵出版社','address':'大兴天宫院'} s = serializers.PublisherSerializer(data=p2) s.is_valid()# 如果数据检测没有问题 Out[5]: True s.validated_data # 可以查看类型,观察到这是一个有序字典 Out[6]: OrderedDict([('name', '图灵出版社'), ('address', '大兴天宫院')]) s.save() # 保存到数据库 Out[7]: <Publisher: 图灵出版社> 选区_173 刷新浏览器 选区_174 在视图里面使用 # 第三次改进 from app01 import serializers # 如果是多个对象,一定要写many = True,就是说我们是多个对象, # many=True告诉程序要用遍历的方式去给我们做序列化 s = serializers.PublisherSerializer(queryset, many=True) import json return HttpResponse(json.dumps(s.data), content_type='application/json') 选区_175 4. 改进自定义序列化模块 因为那些字段,我们已经在模型中创建,没有必要再创建一次,所以我们再进行一次改进 class PublisherSerializer(serializers.ModelSerializer): class Meta: model = models.Publisher # 我们要使用的模型 # 我们要使用的字段 fields = ( 'id', 'name', 'address' ) 选区_176 刷新浏览器,依旧可以正常运行,也就说是我们可以自己去写每一个字段,当然可以用ModelSerializer,直接使用我们的模型(相当于和我们数据库里面的表字段一一对应) 选区_177

优秀的个人博客,低调大师

分离式皮肤资源解决方案探索

前言: 在App开发中,通常需要涉及到皮肤/主题的逻辑,以保证程序风格的多样化,保证符合大多数用户的不同口味。而一个优秀的皮肤管理框架不仅有利于开发者优雅的coding,同时需要做到能够动态切换皮肤,动态更换下载皮肤。 本篇内容从公司产品当前主题管理器的设计引入一种新型的皮肤管理方案。以期解决现有多主题编程时的各种难受,同时能够带来更好的皮肤动态性。 正题: 一. 皮肤/主题资源有哪些? 常用的主题资源有:背景色彩,文字色彩,图片背景,控件样式,字体样式,字体大小,控件尺寸,控件margin-padding.等。 二. 常见的皮肤切换方案有哪些? 1. 对于小型APP来说,设计一套功能完善的皮肤管理框架 稍显多余,因此通常都是以系统自带的 styleable主题切换方式为主。 此种方式,优

优秀的个人博客,低调大师

读写角度,带你了解数仓的IO基本框架

摘要:本文从读取和写入的角度分别描述了行存和列存的IO模型,并对文件结构做了简单介绍。 本文分享自华为云社区《GaussDB(DWS)基本IO框架》,作者: Naibaoofficial。 行存IO管理框架 存储结构 OID(Object identifiers):对象的唯一标识。 每个表存在对应数据库的文件夹中,用relfilenode标识。 例如表row1,可以直接查询对应的文件 test=# select pg_relation_filepath('row1'); pg_relation_filepath ---------------------- base/16385/55984 (1 row) 每个表的读取写入以页(文件块)为基本单位,页的大小是一个BLCKSZ,默认8KB,其结构如下: Tuple保存了当前一行的数据,分为Header和Data两块,头部保存元组的相关信息(列数,事务信息,是否有Toast表等)。 每个Tuple最大为2kb,若Data过大无法压缩至2KB,则采用额外的Toast表存储,此时Tuple内的Data保存Toast表的相关信息。 GaussDB 行存框架: 这里面涉及到几个比较大的内核机制: 本地缓存: 这里面的本地缓存介绍了三个比较常用的缓存结构,这里直接引用了官方的英文解释。 temp_buffers: Sets the maximum number of temporary buffers used by each database session. These are session-local buffers used only for access to temporary tables. work_mem: Specifies the amount of memory to be used by internal sort operations and hash tables before writing to temporary disk files. maintenance_work_mem: Specifies the maximum amount of memory to be used by maintenance operations, such as VACUUM, CREATE INDEX, and ALTER TABLE ADD FOREIGN KEY. 共享内存:可由整个Gaussdb共享 包括shared_buffer和wal_buffer, 分别用来存放Page和Clog,Wal Segment。 WalWriter,BgWriter: 主要是将共享内存的内容落盘,WalWriter一般是在事务提交时就需要落盘,但是有时候可以放弃一定的事务一致性原则,从而让WalWriter异步落盘加快速度。BgWriter负责将shared_buffer中的内容落盘。 外存管理: 负责上层与外存之间的文件交互。 IO管理框架:读取 读取的过程相对简单,就是从物理文件先装到shared_buffer中,然后从shared_buffers返回相关的结果。 shared_buffers中就是以Page为单位进行存储的,因为每个Page的大小是固定的,所以shared_buffers能存放的page个数也就是确定的。这里面就需要考虑一个问题,因为这个资源是共享的,如果一个线程读取了大量的文件,这样势必会使得其他线程的缓存命中率下降。 GaussDB在这里引入了Ringbuffer的机制,可以限制一个线程所使用的shared_buffers的大小,从而解决掉这个问题。 IO管理框架:写入 写入操作是增加的新的元组,Update操作相当于先Delete,再Insert。 INSERT UPDATE 将旧元组标记为Dead,然后插入新的元组,由Vacuum负责清理。当然,这里面Data变为DELETE只是用来描述删除的是此Tuple,实际上Data当中的值是不变的。 写入的整体逻辑: GaussDB行存在写入时,将元组信息先写入到shared_buffers,然后用bgwriter刷入磁盘,这样在事务提交时就可以避免磁盘的IO开销,提升性能,为了保证一致性和恢复,使用wal日志和checkpoints可以实现日志先落盘(也可以异步)和redo等操作。 列存的IO管理框架 列存的存储单元 列存的存储单元为CU(CStore Unit) CU的大小为8k对齐 适合大批量导入的场景 同一列的CU存在一个新文件中,大于1GB时,切换到新文件中。 列存用一个CUDesc的行存表描述CU的相关信息,可以理解成为一个Toast表。 CUDesc:行存表,记录CU的相关信息, 主要属性如下: col_id,cu_id: 第col_id列,第cu_id个CU min, max, row_count, size cu_mode: information mask(RLE,LZ4,Delta表等) cu_pointer:指向每一个CU,记录delete bitmap magic:和CU头部的magic相同,校验使用 CU结构 列存索引 这里介绍两个索引,C-Btree和Psort,这里不做过多介绍。 主要涉及的是IO相关的内容。 C-Btree 索引结构和行存无差别,同样以行存形式存储 C-Btree可以提升点查效率 存储key->ctid(cu_id, offset) 过程: 根据B-tree索引找到ctid集合 对集合进行批量排序(减少IO开销) 在CUDesc找到对应的cu_id,根据offset找到数据 举例,等值查询 n=49, 范围查询 23<n<64。 PSort PSort是一个聚簇索引,对索引进行排序,然后将排序后的索引和行号存入一个新的表,用单独的列存表存储。 简单示意如下,图片来源:https://www.modb.pro/db/108155 IO管理框架:读取 读取过程: 根据where条件,做MIN/MAX过滤的谓词条件 加载CUDesc MIN/MAX过滤 读取CU到CU Cache中 解析并填充 CacheMgr: 用来缓存CU到内存中,可以提高重复查询的性能。 CU的物理文件: 1. CStore_1.0: 当前基本不怎么实用 2. CStore_2.0: 重整了CU的文件结构,避免列数过多导致文件结构复杂。 IO管理框架:写入 列存的插入要分两种情况,少量的插入和大量的插入,列存主要是对大批量数据设计的,因此为了弥补小量插入的打包CU性能开销,设计了一个delta行存表,用来记录插入结果,可以减少膨胀和提升性能,最后定期的整理。 写入框架如下 列存的删除比较简单,如果是delta表,先从delta表中删除满足谓词条件的记录,然后在CUDesc表中更新待删除CU的delete_bitmap。 点击关注,第一时间了解华为云新鲜技术~

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

用户登录
用户注册