库可以轻松同步/区分/更新2个不同的数据源

diffsync的Python项目详细描述


差分同步

DiffSync是一个实用程序库,可用于比较和同步不同的数据集。在

例如,它可以用来比较来自2个资源清册系统的设备列表,如果需要,可以在任一方向同步它们。在

A=DiffSyncSystemA()B=DiffSyncSystemB()A.load()B.load()# Show the difference between both systems, that is, what would change if we applied changes from System B to System Adiff_a_b=A.diff_from(B)print(diff.str())# Update System A to align with the current status of system BA.sync_from(B)# Update System B to align with the current status of system AA.sync_to(B)

入门

为了能够正确比较不同的数据集,DiffSync依赖于两个系统都必须使用的共享数据模型。 具体来说,每个系统或数据集必须提供一个DiffSync“adapter”子类,该子类又将其数据集表示为一个或多个DiffSyncModel数据模型类的实例。在

在比较两个系统时,DiffSync会检测两个系统之间的交集(它们有共同的数据模型,以及每对数据模型之间共享哪些属性),并使用这个交集来比较和/或同步数据。在

用DiffSyncModel定义模型

DiffSyncModel基于Pydantic,并使用Python类型定义每个属性的格式。 每个DiffSyncModel子类都支持以下类级别的属性:

  • _modelname-定义模型的类型;用于标识不同系统之间的通用模型(必需)
  • _identifiers-用作此对象主键的实例字段名列表(必需)
  • _shortname-用于较短名称的实例字段名列表(可选)
  • _attributes-此对象的非标识符实例字段名的列表;用于标识不同系统的数据模型之间的公共字段(可选)
  • _children-Dict of {<model_name>: <field_name>}指示哪些字段存储对子数据模型实例的引用。(可选)

DiffSyncModel instances must be uniquely identified by their unique id, composed of all fields defined in _identifiers. The unique id must be globally meaningful (such as an unique instance name or slug), as it is used to identify object correspondence between differing systems or data sets. It must not be a value that is only locally meaningful, such as a database primary key integer value.

Only fields listed in _identifiers, _attributes, or _children will be potentially included in comparison and synchronization between systems or data sets. Any other fields will be ignored; this allows for a model to additionally contain fields that are only locally relevant (such as database primary key values) and therefore are irrelevant to comparisons.

^{pr2}$

模型之间的关系

目前模型之间的关系在设计上非常松散。不存储对象,建议存储对象的唯一id,并根据需要从存储中检索它。DiffSyncModeladd_child()API将此行为作为默认行为提供。在

使用DiffSync定义系统适配器

DiffSync“adapter”子类必须通过modelname引用对象顶部可用的每个模型,并且必须定义一个top_level属性,以指示应该如何完成差异和同步。在下面的示例中,"site"是唯一的顶层对象,因此同步引擎将只检查所有已知的Site实例和每个站点的所有子对象。在本例中,如上面的代码所示,Devices是Sites的子级,因此这正是预期的逻辑。在

fromdiffsyncimportDiffSyncclassBackendA(DiffSync):site=Sitedevice=Devicetop_level=["site"]

由实现者使用适当的数据填充DiffSync的内部缓存。在下面的例子中,我们使用load()方法来填充缓存,但这不是强制性的,可以用不同的方法来完成。在

将数据存储在DiffSync对象中

要将站点添加到本地缓存/存储,需要将有效的DiffSyncModel对象传递给add()函数。在

classBackendA(DiffSync):[...]defload(self):# Store an individual objectsite=self.site(name="nyc")self.add(site)# Store an object and define it as a child of another objectdevice=self.device(name="rtr-nyc",role="router",site_name="nyc")self.add(device)site.add_child(device)

同步更新远程系统

当通过sync_from()sync_to()执行数据同步时,DiffSync会自动更新内存中的 DiffSyncModel接收适配器的对象。此类的实现者负责确保任何远程系统或数据存储都得到相应的更新。有两种常见的方法可以做到这一点,这取决于它是否更多 便于管理单个记录(如在数据库中)或一次性修改整个数据存储(如在基于文件的数据存储中)。在

管理个人记录

要更新远程系统中的单个记录,您需要扩展您的DiffSyncModel类,为每个模型定义自己的createupdate和/或{}方法。 DiffSyncModel实例存储对其父DiffSync适配器实例的引用,以防您需要使用它从DiffSync的缓存中查找其他模型实例。在

classDevice(DiffSyncModel):[...]@classmethoddefcreate(cls,diffsync,ids,attrs):## TODO add your own logic here to create the device on the remote system# Call the super().create() method to create the in-memory DiffSyncModel instancereturnsuper().create(ids=ids,diffsync=diffsync,attrs=attrs)defupdate(self,attrs):## TODO add your own logic here to update the device on the remote system# Call the super().update() method to update the in-memory DiffSyncModel instancereturnsuper().update(attrs)defdelete(self):## TODO add your own logic here to delete the device on the remote system# Call the super().delete() method to remove the DiffSyncModel instance from its parent DiffSync adaptersuper().delete()returnself

批量/批量修改

如果你愿意的话o在执行所有单独的创建/更新/删除操作后,用最终状态更新整个远程系统(如果“远程系统”是单个YAML或JSON文件,则可能是这种情况),实现此逻辑最容易的地方是sync_complete()回调方法,DiffSync在同步操作完成后自动调用该方法。在

classBackendA(DiffSync):[...]defsync_complete(self,source:DiffSync,diff:Diff,flags:DiffSyncFlags,logger:structlog.BoundLogger):## TODO add your own logic to update the remote system now.# The various parameters passed to this method are for your convenience in implementing more complex logic, and# can be ignored if you do not need them.## The default DiffSync.sync_complete() method does nothing, but it's always a good habit to call super():super().sync_complete(source,diff,flags,logger)

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
java变量始终存储0值。为什么?   如何使用Java/REST将Azure blob从一个存储容器移动到另一个存储容器?   java将commons DBCP从1.2升级到1.4,我应该害怕吗?   java如何使用分隔符拆分字符串?   java使用数组读取json对象   java在groovy中切片字符串   交换数组java的两个邻域元素   java移动用于确定字符串是否为回文的逻辑   java Android应用程序在一个活动中崩溃   java Sparkjava将webapp文件夹设置为静态资源/模板的文件夹   java复杂条件表达式,用户易用。   java如何仅在表存在时从表中选择值   java I无法将数据从Recyclerview传递到其他活动   java数据结构最佳设计(大数据)   java Android从DatePickerDialogFragment中删除日历视图   java将数据从Firebase获取到片段   数组。sort()在java中运行不正常