Last active
June 14, 2019 08:41
-
-
Save w4096/d78177e7efe19c36f87bd4c4429193a6 to your computer and use it in GitHub Desktop.
neo4j 提供了数据导入工具,但是使用命令行输入太繁琐,多有不便。此处提供一个辅助工具帮助导入。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#coding=utf-8 | |
import sys | |
import json | |
import os | |
import logging | |
import glob | |
logging.basicConfig(level=logging.DEBUG, | |
format="%(asctime)s - %(message)s", | |
datefmt='%Y-%m-%d %H:%M:%S') | |
def build_command_argument(config): | |
database = config.get('database', '') | |
nodes = config.get('nodes', []) | |
relationships = config.get('relationships', []) | |
delimiter = config.get('delimiter', ',') | |
array_delimiter = config.get('array-delimiter', ';') | |
quote = config.get('quote', '"') | |
ignore_duplicate_nodes = config.get('ignore-duplicate-nodes', False) | |
ignore_missing_nodes = config.get('ignore-missing-nodes', False) | |
multiline_field = config.get("multiline_field", False) | |
cmd = '' | |
if database: | |
cmd += ' --database=' + database | |
cmd += ' ' + build_nodes_arguments(nodes) | |
cmd += ' ' + build_relationships_arguments(relationships) | |
cmd += " --delimiter={0}{1}{0}".format('"', delimiter) | |
cmd += " --array-delimiter {0}{1}{0}".format('"', array_delimiter) | |
if quote != '"': | |
cmd += " --quote {0}{1}{0}".format('"', quote) | |
if ignore_duplicate_nodes: | |
cmd += " --ignore-duplicate-nodes=true" | |
if ignore_missing_nodes: | |
cmd += " --ignore-missing-nodes=true" | |
if multiline_field: | |
cmd += " --multiline-fields=true" | |
return cmd | |
def assert_file_exists(file): | |
matched_files = glob.glob(file) | |
if not matched_files: | |
message = 'has no matched file for pattern: ' + file | |
logging.error(message) | |
exit(-1) | |
def build_nodes_arguments(nodes): | |
if not nodes: | |
logging.error('Except at least one node file, but zero founded.') | |
arg = '' | |
for node in nodes: | |
labels = node.get('labels', []) | |
header = node.get('header', '') | |
file = node.get('file', '') | |
if labels: | |
arg += ' --nodes:{}='.format(':'.join(labels)) | |
else: | |
arg += ' --nodes=' | |
files = [] | |
if header: | |
assert_file_exists(header) | |
files.append(header) | |
assert_file_exists(file) | |
files.append(file) | |
arg += '"{}"'.format(",".join(files)) | |
return arg | |
def build_relationships_arguments(relationships): | |
arg = '' | |
for relation in relationships: | |
types = relation.get('types', []) | |
header = relation.get('header', '') | |
file = relation.get('file', '') | |
if types: | |
arg += ' --relationships:{}='.format(':'.join(types)) | |
else: | |
arg += ' --relationships=' | |
files = [] | |
if header: | |
assert_file_exists(header) | |
files.append(header) | |
assert_file_exists(file) | |
files.append(file) | |
arg += '"{}"'.format(",".join(files)) | |
return arg | |
def print_usage(): | |
logging.info('usage:\n\n python import.py config.json') | |
if __name__ == '__main__': | |
if len(sys.argv) < 2: | |
print_usage() | |
sys.exit() | |
config_file = sys.argv[1] | |
with open(config_file, encoding='utf-8') as fin: | |
config = json.load(fin) | |
cmd_argument = build_command_argument(config) | |
neo4j_home = config['neo4j_home'] | |
if not neo4j_home: | |
logging.error('neo4j_home must be specified.') | |
sys.exit() | |
os.environ['NEO4J_HOME'] = neo4j_home | |
cmd = neo4j_home + '/bin/neo4j-admin import ' + cmd_argument | |
# print(cmd) | |
os.system(cmd) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
使用导入工具
如果需要要导入的文件很多,命令行就会很长。这里提供了一段 python 脚本,通过编写配置文件,生成相应的命令并执行,以缓解输入很长命令的麻烦。
用法如下:
其中
config.json
为配置文件,文件格式如下:说明:
=> neo4j_home
此字段用于指定 neo4j 的主目录,便于定位可执行文件
neo4j-admin
的位置。=> nodes / relationships
提供节点和关系的数据。
labels/types
:在节点和关系对应的 csv 文件中,可以不添加
:LABEL
或者:TYPE
列,而在配置文件中使用labes
或types
指出。因为一个节点可以有多种 label,相似地一个关系也可以有多个 type,因此这里使用数组。header
:CSV 文件含两个部分,header 和 body,可以将 header 部分单独放在一个文件中。
=> delimiter
指定 csv 的列分隔符,默认为英文逗号 (
,
)。=> array-delimiter
csv 文件中某个字段为数组时,数组元素间的分隔符。在生成 CSV 文件的时候,某个属性是数组,将其元素使用
array-delimiter
指定的字符拼接起来,在读入 neo4j 之后,该字段依然能被识别为数组。=> quote
在 csv 文件中,某个字段的内容中出现了
delimiter
,这会导致某一行列数增加,csv 格式就会出错。解决的办法是,将此字段使用 quote 括起来。括起来的内容,出现delimiter
不会被解释为列分隔符。因此这里的
quote
需要根据生成 CSV 时的设置来决定。=> ignore-duplicate-nodes
是否忽略重复的节点,即 ID 重复的是否忽略,默认为 false。
=> ignore-missing-nodes
某个关系指定的节点不存在时,是否忽略该条关系。如果不忽略,就会报错。默认为 false,即不忽略。