From e0aeddbbf54a3b0dff290cd5b161d4270a68fcc7 Mon Sep 17 00:00:00 2001 From: Matija Date: Fri, 8 Sep 2023 12:51:19 +0200 Subject: [PATCH 1/2] Write docs for csv graph export --- .../python/export-util/csv_graph.png | Bin 0 -> 35428 bytes mage/query-modules/python/export-util.md | 351 +++++++++++++++++- 2 files changed, 350 insertions(+), 1 deletion(-) create mode 100644 mage/data/query-modules/python/export-util/csv_graph.png diff --git a/mage/data/query-modules/python/export-util/csv_graph.png b/mage/data/query-modules/python/export-util/csv_graph.png new file mode 100644 index 0000000000000000000000000000000000000000..1203b8e560dbf0c08d261855828a386f9b4e435d GIT binary patch literal 35428 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
  • HrDy!ip8eG2 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 literal 0 HcmV?d00001 diff --git a/mage/query-modules/python/export-util.md b/mage/query-modules/python/export-util.md index 1f7cb7b09e5..73a0b336dfb 100644 --- a/mage/query-modules/python/export-util.md +++ b/mage/query-modules/python/export-util.md @@ -21,7 +21,7 @@ export const Highlight = ({children, color}) => ( ); Module for exporting a graph database or query results in different formats. Currently, this -module supports [**exporting database to a JSON file format**](#jsonpath) and [**exporting query results in a CSV file format**](#csv_queryquery-file_path-stream). +module supports [**exporting database to a JSON file format**](#jsonpath), [**exporting query results in a CSV file format**](#csv_queryquery-file_path-stream) and [**exporting graph nodes and relationships to CSV file format**](#csv_graphnodes_list-relationships_list-path-config). [![docs-source](https://img.shields.io/badge/source-export_util-FB6E00?logo=github&style=for-the-badge)](https://github.com/memgraph/mage/blob/main/python/export_util.py) @@ -392,3 +392,352 @@ Erica Sinclair,Priah Ferguson,Stranger Things,2016,"['Matt Duffer', 'Ross Duffer + + +### `csv_graph(nodes_list, relationships_list, path, config)` + +This function exports the given lists of nodes and relationships into a CSV file. Additional configurations can be passed inside the `config` map to further specify the export. + +#### Input: + +- `nodes_list: List[Node]` ➡ list of nodes which are to be exported. +- `relationships_list: List[Relationship]` ➡ list of relationships which are to be exported. +- `path: string default = ""` ➡ path where the exported file will be saved. If left as default, the file will be saved in the current directory, as `exported_file.csv` (note: path must end with the filename, for example, `folder_outer/folder/file.csv` is a valid path, `folder_outer/folder/` is not). +- `config: Map default = {}` ➡ configuration map, default is {}. + +#### Configurations: + +| Configuration Key | Default Value | Description | +|-------------------|---------------|-------------| +| `delimiter` | `,` | The delimiter used to separate fields in the CSV file. | +| `quotes` | `All` | The type of quoting to apply to fields in the CSV file. Possible values: `none`: no quotes added, `ifNeeded`: quotes are added only when necessary, `All`: always quote. If anything other than the presented options is passed as a config, it is as if the default value is chosen. | +| `separateHeader` | `False` | Indicates whether the CSV file header should be separated into its own file. If `True`, a file named `header.csv` will be created in the specified or default directory.| +| `stream` | `False` | Indicates whether the data should be returned as a stream rather than a file. If `True`, no file will be saved. | + +#### Output: + +- `data: string` ➡ if stream is `True`, a string stream representation of data, otherwise `""`. +- `path: string` ➡ path to the exported CSV file. + + + +#### File structure: + +The CSV file columns are structured this way: + +| _id | _labels| node_properties_sorted | _start | _end | _type | relationship_properties_sorted | +|------|-----|--------|-------------|--------|------|-------| +|node id| node labels | alphabetically sorted properties of all nodes (all node properties present in the graph) | id of the start node of a relationship | id of the end node of a relationship | type of relationship | alphabetically sorted properties of all relationships (all relationship properties present in the graph) | + +For example, consider a simple graph, created with this cypher query: + +```cypher +CREATE (d:Dog {name: "Rex", breed: "Dalmatian"})-[i:IS_OWNED_BY {rel_property: 30}]->(h:Human {name: "Carl", age: 50}); +``` + +The id of the Dog node is 0, and the id of the Human node is 1. +Exporting would result in a CSV file structured this way: + +| _id | _labels| age | breed | name| _start | _end | _type | rel_property | +|-----|--------|-----|-------|-----|--------|------|-------|--------------| +|0 | :Dog | | Dalmatian| Rex | | | | | +|1 | :Human | 50 | | Carl | | | | | +| | | | | | 0 | 1 | IS_OWNED_BY | 30 | + + +#### Usage without configurations: + +In this section, simple usage without any configuration is displayed. + + + + + +```cypher +CREATE (d:Dog {name: "Rex", breed: "Dalmatian"})-[i:IS_OWNED_BY {rel_property: 30}]->(h:Human {name: "Carl", age: 50}); +CREATE (hs:Human:Soldier {branch : "Army"})-[t:TRAINS { duration: duration("P10D")}]->(d:Dog:K9 {name: "Bolt", years_of_service: 3}); +``` + + + + + + + + + + +```cypher +MATCH (n) +OPTIONAL MATCH (n)-[r]-() +WITH COLLECT(DISTINCT n) AS nodes, COLLECT(DISTINCT r) AS relationships +CALL export_util.csv_graph(nodes, relationships, "/demonstration/export/Documents/file.csv", {}) YIELD data, path RETURN data, path; +``` + + + + + +| _id | _labels | age | branch | breed | name | years_of_service | _start | _end | _type | duration | rel_property | +|-----|-----------------|-----|--------|----------|------|------------------|--------|------|-----------------|----------------------------|-----------------| +| 0 | :Dog | | | Dalmatian| Rex | | | | | | | +| 1 | :Human | 50 | | | Carl | | | | | | | +| 2 | :Human:Soldier | | Army | | | | | | | | | +| 3 | :Dog:K9 | | | | Bolt | 3 | | | | | | +| | | | | | | | 0 | 1 | IS_OWNED_BY | | 30 | +| | | | | | | | 2 | 3 | TRAINS | duration(10 days,0:00:00) | | + + + + + +```plaintext + +"_id","_labels","age","branch","breed","name","years_of_service","_start","_end","_type","duration","rel_property" +"0",":Dog","","","Dalmatian","Rex","","","","","","" +"1",":Human","50","","","Carl","","","","","","" +"2",":Human:Soldier","","Army","","","","","","","","" +"3",":Dog:K9","","","","Bolt","3","","","","","" +"","","","","","","","0","1","IS_OWNED_BY","","30" +"","","","","","","","2","3","TRAINS","duration(10 days, 0:00:00)","" + +``` + + + + + + +#### Usage with configurations: + +In this section, usage with configurations is displayed. The graph used is the same one as in usage without configurations. + +##### Delimiter + +Example of using a different delimiter. + + + + +```cypher +MATCH (n) +OPTIONAL MATCH (n)-[r]-() +WITH COLLECT(DISTINCT n) AS nodes, COLLECT(DISTINCT r) AS relationships +CALL export_util.csv_graph(nodes, relationships, "/demonstration/export/Documents/file.csv", {delimiter : "|"}) YIELD data, path RETURN data, path; +``` + + + + + +```plaintext + +"_id"|"_labels"|"age"|"branch"|"breed"|"name"|"years_of_service"|"_start"|"_end"|"_type"|"duration"|"rel_property" +"0"|":Dog"|""|""|"Dalmatian"|"Rex"|""|""|""|""|""|"" +"1"|":Human"|"50"|""|""|"Carl"|""|""|""|""|""|"" +"2"|":Human:Soldier"|""|"Army"|""|""|""|""|""|""|""|"" +"3"|":Dog:K9"|""|""|""|"Bolt"|"3"|""|""|""|""|"" +""|""|""|""|""|""|""|"0"|"1"|"IS_OWNED_BY"|""|"30" +""|""|""|""|""|""|""|"2"|"3"|"TRAINS"|"duration(10 days, 0:00:00)"|"" + + +``` + + + + + +##### Quoting: + +Example of using different quoting styles. + + + + +```cypher +MATCH (n) +OPTIONAL MATCH (n)-[r]-() +WITH COLLECT(DISTINCT n) AS nodes, COLLECT(DISTINCT r) AS relationships +CALL export_util.csv_graph(nodes, relationships, "/demonstration/export/Documents/file.csv", {quotes : "All"}) YIELD data, path RETURN data, path; +``` + + + + + +```plaintext + +"_id","_labels","age","branch","breed","name","years_of_service","_start","_end","_type","duration","rel_property" +"0",":Dog","","","Dalmatian","Rex","","","","","","" +"1",":Human","50","","","Carl","","","","","","" +"2",":Human:Soldier","","Army","","","","","","","","" +"3",":Dog:K9","","","","Bolt","3","","","","","" +"","","","","","","","0","1","IS_OWNED_BY","","30" +"","","","","","","","2","3","TRAINS","duration(10 days, 0:00:00)","" + + +``` + + + + + +```cypher +MATCH (n) +OPTIONAL MATCH (n)-[r]-() +WITH COLLECT(DISTINCT n) AS nodes, COLLECT(DISTINCT r) AS relationships +CALL export_util.csv_graph(nodes, relationships, "/demonstration/export/Documents/file.csv", {quotes : "ifNeeded"}) YIELD data, path RETURN data, path; +``` + + + + + +```plaintext + +_id,_labels,age,branch,breed,name,years_of_service,_start,_end,_type,duration,rel_property +0,:Dog,,,Dalmatian,Rex,,,,,, +1,:Human,50,,,Carl,,,,,, +2,:Human:Soldier,,Army,,,,,,,, +3,:Dog:K9,,,,Bolt,3,,,,, +,,,,,,,0,1,IS_OWNED_BY,,30 +,,,,,,,2,3,TRAINS,"duration(10 days, 0:00:00)", + +``` + + + + + +```cypher +MATCH (n) +OPTIONAL MATCH (n)-[r]-() +WITH COLLECT(DISTINCT n) AS nodes, COLLECT(DISTINCT r) AS relationships +CALL export_util.csv_graph(nodes, relationships, "/demonstration/export/Documents/file.csv", {quotes : "none"}) YIELD data, path RETURN data, path; +``` + + + + + +```plaintext + +_id,_labels,age,branch,breed,name,years_of_service,_start,_end,_type,duration,rel_property +0,:Dog,,,Dalmatian,Rex,,,,,, +1,:Human,50,,,Carl,,,,,, +2,:Human:Soldier,,Army,,,,,,,, +3,:Dog:K9,,,,Bolt,3,,,,, +,,,,,,,0,1,IS_OWNED_BY,,30 +,,,,,,,2,3,TRAINS,duration(10 days\, 0:00:00), + + +``` + + + + + + +##### SeparateHeader: + +Example of separating the header. + + + + +```cypher +MATCH (n) +OPTIONAL MATCH (n)-[r]-() +WITH COLLECT(DISTINCT n) AS nodes, COLLECT(DISTINCT r) AS relationships +CALL export_util.csv_graph(nodes, relationships, "/demonstration/export/Documents/file.csv", {separateHeader: true}) YIELD data, path RETURN data, path; +``` + + + + + +```plaintext + +"_id","_labels","age","branch","breed","name","years_of_service","_start","_end","_type","duration","rel_property" + +``` + + + + + +```plaintext +"0",":Dog","","","Dalmatian","Rex","","","","","","" +"1",":Human","50","","","Carl","","","","","","" +"2",":Human:Soldier","","Army","","","","","","","","" +"3",":Dog:K9","","","","Bolt","3","","","","","" +"","","","","","","","0","1","IS_OWNED_BY","","30" +"","","","","","","","2","3","TRAINS","duration(10 days, 0:00:00)","" + +``` + + + + + +##### Stream: + +Example of exporting a file to stream. When stream is `True`, the CSV file is not saved, so the file path can be set as `""`, as it will be ignored. + + + +```cypher +MATCH (n) +OPTIONAL MATCH (n)-[r]-() +WITH COLLECT(DISTINCT n) AS nodes, COLLECT(DISTINCT r) AS relationships +CALL export_util.csv_graph(nodes, relationships, "", {stream: True}) YIELD data, path RETURN data; +``` + +Stream: + +```plaintext +"_id","_labels","age","branch","breed","name","years_of_service","_start","_end","_type","duration","rel_property" +"0",":Dog","","","Dalmatian","Rex","","","","","","" +"1",":Human","50","","","Carl","","","","","","" +"2",":Human:Soldier","","Army","","","","","","","","" +"3",":Dog:K9","","","","Bolt","3","","","","","" +"","","","","","","","0","1","IS_OWNED_BY","","30" +"","","","","","","","2","3","TRAINS","duration(10 days, 0:00:00)","" + +``` \ No newline at end of file From bac0d645f614b0b71cf1ccc0ed07006f9b39a75b Mon Sep 17 00:00:00 2001 From: Vlasta <95473291+vpavicic@users.noreply.github.com> Date: Fri, 8 Sep 2023 14:38:42 +0200 Subject: [PATCH 2/2] Apply suggestions from code review --- mage/query-modules/python/export-util.md | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/mage/query-modules/python/export-util.md b/mage/query-modules/python/export-util.md index 73a0b336dfb..124287ba0a5 100644 --- a/mage/query-modules/python/export-util.md +++ b/mage/query-modules/python/export-util.md @@ -429,14 +429,14 @@ The CSV file columns are structured this way: |------|-----|--------|-------------|--------|------|-------| |node id| node labels | alphabetically sorted properties of all nodes (all node properties present in the graph) | id of the start node of a relationship | id of the end node of a relationship | type of relationship | alphabetically sorted properties of all relationships (all relationship properties present in the graph) | -For example, consider a simple graph, created with this cypher query: +For example, consider a simple graph created with the following Cypher query: ```cypher CREATE (d:Dog {name: "Rex", breed: "Dalmatian"})-[i:IS_OWNED_BY {rel_property: 30}]->(h:Human {name: "Carl", age: 50}); ``` -The id of the Dog node is 0, and the id of the Human node is 1. -Exporting would result in a CSV file structured this way: +The `Dog` node's ID is 0, and the `Human` node's ID is 1. +Exporting would result in a CSV file structured in the following way: | _id | _labels| age | breed | name| _start | _end | _type | rel_property | |-----|--------|-----|-------|-----|--------|------|-------|--------------| @@ -520,7 +520,7 @@ CALL export_util.csv_graph(nodes, relationships, "/demonstration/export/Document #### Usage with configurations: -In this section, usage with configurations is displayed. The graph used is the same one as in usage without configurations. +In this section, usage with configurations is displayed. The same graph is used as in the usage without configurations. ##### Delimiter @@ -721,7 +721,6 @@ CALL export_util.csv_graph(nodes, relationships, "/demonstration/export/Document Example of exporting a file to stream. When stream is `True`, the CSV file is not saved, so the file path can be set as `""`, as it will be ignored. - ```cypher MATCH (n) OPTIONAL MATCH (n)-[r]-()