如何在使用 Django-admin 时实时同步 postgres 数据库与 neo4j?
How to sync postgres database with neo4j in realtime while using Django-admin?
所以目前我正在开发一个 Django 项目,我有两个不同的数据库。一个是 PostgreSQL,第二个是 Neo4j。我想要的是两个数据库之间的实时同步。我正在使用 Django-admin 面板在 Postgres 数据库中进行 crud 操作。现在我也希望 neo4j 数据库中的每个 crud 操作更新。但我不知道该怎么做。
您可以选择几条路线。我想你会想要将 Postgres 作为你的主要 Django 数据库并使用 Neo4j 作为附属数据库,而不是由 Django 框架管理。您可以使用类似于 this post 的 Neo4j 客户端库来实现这一点,以便您自己与图形数据库进行交互。
为了让 Neo4j 与 Django 管理的 Postgres 保持同步,我认为 signals 将成为你最好的朋友,特别是 post_save
信号。本质上,只要你保存 Django 模型,这个信号就会触发一个函数,你可以编写这个函数来使用 Neo4j 客户端 API 来反映图形数据库中的变化。
但是,根据您的模型的复杂程度,确定更改了哪些字段以仅更新这些字段可能会变得棘手。前一段时间我遇到了类似的问题,并使用了这个自定义 Mixin(我找不到原作者,但将其保留在我的笔记中):
from django.forms import model_to_dict
import logging
logger = logging.getLogger(__name__)
class ModelDiffMixin(object):
"""
A model mixin that tracks model fields' values and provide some useful api
to know what fields have been changed.
"""
def __init__(self, *args, **kwargs):
super(ModelDiffMixin, self).__init__(*args, **kwargs)
self.__initial = self._dict
@property
def diff(self):
d1 = self.__initial
d2 = self._dict
diffs = [(k, (v, d2[k])) for k, v in d1.items() if v != d2[k]]
return dict(diffs)
@property
def has_changed(self):
return bool(self.diff)
@property
def changed_fields(self):
return self.diff.keys()
def get_field_diff(self, field_name):
"""
Returns a diff for field if it's changed and None otherwise.
"""
return self.diff.get(field_name, None)
def save(self, *args, **kwargs):
"""
Saves model and set initial state.
"""
super(ModelDiffMixin, self).save(*args, **kwargs)
self.__initial = self._dict
@property
def _dict(self):
return model_to_dict(self, fields=[field.name for field in
self._meta.fields])
如果你将这个 Mixin 实现到你的模型中以与 Neo4j 同步,那么在 post_save
信号处理程序中你可以调用 model.diff
或 model.changed_fields
来查看哪些属性需要在 Neo4j 节点上更新,而不是删除整个节点并重新创建它和所有关系。
所以目前我正在开发一个 Django 项目,我有两个不同的数据库。一个是 PostgreSQL,第二个是 Neo4j。我想要的是两个数据库之间的实时同步。我正在使用 Django-admin 面板在 Postgres 数据库中进行 crud 操作。现在我也希望 neo4j 数据库中的每个 crud 操作更新。但我不知道该怎么做。
您可以选择几条路线。我想你会想要将 Postgres 作为你的主要 Django 数据库并使用 Neo4j 作为附属数据库,而不是由 Django 框架管理。您可以使用类似于 this post 的 Neo4j 客户端库来实现这一点,以便您自己与图形数据库进行交互。
为了让 Neo4j 与 Django 管理的 Postgres 保持同步,我认为 signals 将成为你最好的朋友,特别是 post_save
信号。本质上,只要你保存 Django 模型,这个信号就会触发一个函数,你可以编写这个函数来使用 Neo4j 客户端 API 来反映图形数据库中的变化。
但是,根据您的模型的复杂程度,确定更改了哪些字段以仅更新这些字段可能会变得棘手。前一段时间我遇到了类似的问题,并使用了这个自定义 Mixin(我找不到原作者,但将其保留在我的笔记中):
from django.forms import model_to_dict
import logging
logger = logging.getLogger(__name__)
class ModelDiffMixin(object):
"""
A model mixin that tracks model fields' values and provide some useful api
to know what fields have been changed.
"""
def __init__(self, *args, **kwargs):
super(ModelDiffMixin, self).__init__(*args, **kwargs)
self.__initial = self._dict
@property
def diff(self):
d1 = self.__initial
d2 = self._dict
diffs = [(k, (v, d2[k])) for k, v in d1.items() if v != d2[k]]
return dict(diffs)
@property
def has_changed(self):
return bool(self.diff)
@property
def changed_fields(self):
return self.diff.keys()
def get_field_diff(self, field_name):
"""
Returns a diff for field if it's changed and None otherwise.
"""
return self.diff.get(field_name, None)
def save(self, *args, **kwargs):
"""
Saves model and set initial state.
"""
super(ModelDiffMixin, self).save(*args, **kwargs)
self.__initial = self._dict
@property
def _dict(self):
return model_to_dict(self, fields=[field.name for field in
self._meta.fields])
如果你将这个 Mixin 实现到你的模型中以与 Neo4j 同步,那么在 post_save
信号处理程序中你可以调用 model.diff
或 model.changed_fields
来查看哪些属性需要在 Neo4j 节点上更新,而不是删除整个节点并重新创建它和所有关系。