The compiler builds a query string from an AST. To execute queries, you'll work with the compiler's AST interface.
The OGM's interface is built on Nodes and Props.
At the lowest level, NeoAlchemy uses an AST to build and execute queries. An AST is built upon Element subclasses, each storing information about itself. This information is used by a Compiler subclass to turn each Element into a string. It does this using its visit_xxx methods, which match up to the __visit_name__ property of Element.
The declarative bits (hereby known as the OGM) are built on the Node model base class. Node subclasses are models of labeled nodes in Neo4j. They have Prop attributes, which store the name of the property inside Neo4j, and a PropType instance which handles type coercion to and from Neo4j.
When a Node class is defined, the NodeMeta metaclass initializes a few things. First, it creates a _neo_state dict on the new class, which will store the property data retrieved from the database (this allows easy implementation of aliased properties).
Second, it sets _node_info to an instance of NodeInfo. This class stores metadata about the Node class, such as a set of all its Prop objects. It also creates a NodeImpl instance, which handles implementation details of Nodes, such as inflation of a Node instance from DB properties. Lastly, NodeMeta initializes any NodeManager instances on the class, so the managers know what Node subclass to act on.
Prop objects accept an instance of PropType (or just the class, if it requires no arguments). PropType classes
Variables can be anonymous or named. Either way, a variable needs to know its type, because it needs to know when the same variable can be used in other places. For anonymous variables, this can simply be the FQDN of the OGM Node class. To make things easy, the Node class should have a key property.
Properties can either be a bound parameter (as in ({props})) or a collection of single keys to literal values or other nodes' properties, e.g.:
{
'a': 1,
'b': 'test',
'c': [1, 2, 3],
}
or
{
'a': MyNode.x,
'b': YourNode.y,
'c': alias_of_node.z,
}