The Id column get a value of None in py2neo.ogm - py2neo

I'm working with the interface py2neo to access the neo4j database out of python. I want to used the autogenerated Id column in an OGM model as a property. But my idea doesn't work. Please look a the example:
from py2neo import Graph, Node, Relationship
from py2neo.ogm import GraphObject, Property, RelatedTo, RelatedFrom
class Material(GraphObject):
id = Property()
name = Property()
description = Property()
I insert the values into the system:
mat_f01 = Node('Material', name='F01', description='Fert Product 01')
mat_f02 = Node('Material', name='F02', description='Fert Product 02')
In the neo4j browser the record are displayed as followed - with the id column:
<id>:178 description: Fert Product 02 name: F02
If I look to the same records in flask the Id column contains the value None. It should contain 177 and 178.
description id name
Fert Product 01 Fert None F01
Fert Product 03 Fert None F03
Many thanks in advance.

The node ID has no correlation with the properties on that node. It is more of an internal attribute, closer to the address of a variable than an auto-generated ID. It is exposed by Neo4j as a convenience but should not be used for anything that requires a stable node reference as it can't provide those guarantees of stability.
If you want a unique identifier property then I recommend a UUID4 hex string instead. You can generate one of these in Python via the uuid module, and it should be guaranteed unique for all practical purposes.

Related

Can I specify my own identifier ID as the relationship IDs in APOC.export?

Currently, it seems the relationship output by apoc.export function:
CALL apoc.export.csv.data( [], R, null, {stream:true}) YIELD data AS rdata
RETURN mdata, ndata, rdata
The format is:
_start _end _type
18701 19076 hasMember
The '18701' & '19076' are neo4j's internal ids. Can I use my own id from the node's identifier as the relationship connector? My own node identifier is always guaranteed to be unique. I want to periodically export KG nodes and relationships as KG grows overtime. In such a case, can the IDs always be unique among all nodes in the entire graph?
The possibility of getting duplicate nodes and relationships when using apoc.import.csv (even when ignoreDuplicateNodes is false, which is the default) is a known issue (see issues 1046 and 1048).
Unfortunately, issue 1048 was closed by its submitter even though is was not fixed.
You may want to open a new issue.

Neo4j SDN 4 emulate sequence object(not UUID)

Is it possible in Neo4j or SDN4 to create/emulate something similar to a PostgreSQL sequence database object?
I need this thread safe functionality in order to be able to ask it for next, unique Long value. I'm going to use this value as a surrogate key for my entities.
UPDATED
I don't want to go with UUID because I have to expose these IDs within my web application url parameters and in case of UUID my urls look awful. I want to go with a plain Long values for IDs like StackOverflow does, for example:
stackoverflow.com/questions/42228501/neo4j-sdn-4-emulate-sequence-objectnot-uuid
This can be done with user procedures and functions. As an example:
package sequence;
import org.neo4j.procedure.*;
import java.util.concurrent.atomic.AtomicInteger;
public class Next {
private static AtomicInteger sequence = new AtomicInteger(0);
#UserFunction
public synchronized Number next() {
return sequence.incrementAndGet();
}
}
The problem of this example is that when the server is restarted the counter will be set to zero.
So it is necessary to keep the last value of the counter. This can be done using these examples:
https://maxdemarzi.com/2015/03/25/triggers-in-neo4j/
https://github.com/neo4j-contrib/neo4j-apoc-procedures/blob/master/src/main/java/apoc/trigger/Trigger.java
No. As far as I'm aware there isn't any similar functionality to sequences or auto increment identifiers in Neo4j. This question has also been asked a few times in the past.
The APOC project might be worth checking out for this though. There seems to be a request to add it.
If your main interest is in having a way to generate unique IDs, and you do not care if the unique IDs are strings, then you should consider using the APOC facilities for generating UUIDs.
There is an APOC function that generates a UUID, apoc.create.uuid. In older versions of APOC, this is a procedure that must be invoked using the CALL syntax. For example, to create and return a single Foo node with a new UUID:
CREATE (f:Foo {uuid: apoc.create.uuid()})
RETURN f;
There is also an APOC procedure, apoc.create.uuids(count), that generates a specified number of UUIDs. For example, to create and return 5 Foo nodes with new UUIDs:
CALL apoc.create.uuids(5) YIELD uuid
CREATE (f:Foo {uuid: uuid})
RETURN f;
The most simplest way in Neo4j is to disable ids reuse and use node Graph ID like sequencer.
https://neo4j.com/docs/operations-manual/current/reference/configuration-settings/
Table A.83. dbms.ids.reuse.types.override
Description: Specified names of id types (comma separated) that should be reused. Currently only 'node' and 'relationship' types are supported.
Valid values: dbms.ids.reuse.types.override is a list separated by "," where items are one of NODE, RELATIONSHIP
Default value: [RELATIONSHIP, NODE]

Using labels in Batch import

In the new 2.0 branch of the NEO4J batch-importer,
To specify a label, I believe one must specify the header,
Using the example from the readme.md and wiki:
name l:label age works_on
Michael Person,Father 37 neo4j
Selina Person,Child 14
Rana Person,Child 6
Selma Person,Child 4
Does the header always have to follow the following format of being l:label and
What does the comma do and is it optional?
ie. What does person,Father represent? label,???
I believe in this case Person is the label but I'm curious how can I query (in cypher) the label value in this case either Father or Child.
I think if you wanted to explicitly assign the type of some property you would use colon + type for that, i.e.
name:String age:int
and :label is used after the fashion of a data type to signal that the value(s) in a field is a node label or a relationship type. Since labels are not name/value pairs like properties, I would think the l in l:label doesn't really do anything.

Integrating Quick books items data using QBFC

I am importing Quick books item data from quick books to CSV file using QBFC.
I have seen few fields have same value(103).
ParentRefType = 103
SalesTaxCodeRefType = 103
ExpenseAccountType = 103
PrefVendorType = 103
PurchaseTaxCodeType = 103
Find the file here
Let me know why ? I does not see this values directly form Quick book application.
I hope this values coming from background.
The short answer is that 103 refers to the FullName Reference Type. And yes, these values are coming from the "background" of Quickbooks and QBFC so you will likely not see them anywhere in the Quickbooks UI.
All of the fields you listed above are Reference Types of a Quickbooks object (i.e. Parent, SalesTaxCode, ExpenseAccount, etc). You can reference an object through two means: a ListID or a FullName. The Type of the reference indicates whether or not the object is using a ListID reference or a FullName reference.
The integer 103 appears to be the internal identifier for a FullName reference type. Notice in your export file (Item.csv) that all of the reference objects use the FullName type to reference objects (see the columns ParentRefFullName, SalesTaxCodeRefFullName, ExpenseAccountRefFullName, etc). Notice also that the columns immediately after these are the Ref Type columns (i.e. ParentRefType, SalesTaxCodeRefType, etc). These Ref Type columns are set to 103 whenever the cell to the left (the FullName cell) contains a value. When there is no FullName reference, the Type column contains a zero (which I'm assuming means Ref Type Not Known or something similar).
The QBFC Quick Reference states the following (under the IQBBaseRef definition):
IQBBaseRef is used for all qbXML "object references," which refer to objects. For example, an
AccountRef refers to an account in the chart of accounts. If a request specifies both ListID
and FullName, QuickBooks will use only the ListID.
That last sentence is important to note. A ListID reference takes priority over a FullName reference. It appears though that there are no ListID references used in your export file.

Node identifiers in neo4j

I'm new to Neo4j - just started playing with it yesterday evening.
I've notice all nodes are identified by an auto-incremented integer that is generated during node creation - is this always the case?
My dataset has natural string keys so I'd like to avoid having to map between the Neo4j assigned ids and my own. Is it possible to use string identifiers instead?
Think of the node-id as an implementation detail (like the rowid of relational databases, can be used to identify nodes but should not be relied on to be never reused).
You would add your natural keys as properties to the node and then index your nodes with the natural key (or enable auto-indexing for them).
E..g in the Java API:
Index<Node> idIndex = db.index().forNodes("identifiers");
Node n = db.createNode();
n.setProperty("id", "my-natural-key");
idIndex.add(n, "id",n.getProperty("id"));
// later
Node n = idIndex.get("id","my-natural-key").getSingle(); // node or null
With auto-indexer you would enable auto-indexing for your "id" field.
// via configuration
GraphDatabaseService db = new EmbeddedGraphDatabase("path/to/db",
MapUtils.stringMap(
Config.NODE_KEYS_INDEXABLE, "id", Config.NODE_AUTO_INDEXING, "true" ));
// programmatic (not persistent)
db.index().getNodeAutoIndexer().startAutoIndexingProperty( "id" );
// Nodes with property "id" will be automatically indexed at tx-commit
Node n = db.createNode();
n.setProperty("id", "my-natural-key");
// Usage
ReadableIndex<Node> autoIndex = db.index().getNodeAutoIndexer().getAutoIndex();
Node n = autoIndex.get("id","my-natural-key").getSingle();
See: http://docs.neo4j.org/chunked/milestone/auto-indexing.html
And: http://docs.neo4j.org/chunked/milestone/indexing.html
This should help:
Create the index to back automatic indexing during batch import We
know that if auto indexing is enabled in neo4j.properties, each node
that is created will be added to an index named node_auto_index. Now,
here’s the cool bit. If we add the original manual index (at the time
of batch import) and name it as node_auto_index and enable auto
indexing in neo4j, then the batch-inserted nodes will appear as if
auto-indexed. And from there on each time you create a node, the node
will get indexed as well.**
Source : Identifying nodes with Custom Keys
According Neo docs there should be automatic indexes in place
http://neo4j.com/docs/stable/query-schema-index.html
but there's still a lot of limitations
Beyond all answers still neo4j creates its own ids to work faster and serve better. Please make sure internal system does not conflict between ids then it will create nodes with same properties and shows in the system as empty nodes.
the ID's generated are default and cant be modified by users. user can use your string identifiers as a property for that node.

Resources