数据类型和 Cypher 类型映射
本节中的表格显示了 Cypher 数据类型和 Python 类型之间的映射。
核心类型
Cypher 类型 | Python 类型 |
---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
有关完整文档,请参阅 API 文档 - 核心数据类型。
时间类型
时间数据类型由neo4j.time
模块实现。它提供了一组符合 ISO-8601 和 Cypher 的类型,类似于 Python 原生datetime
模块中的类型。要转换驱动程序和原生类型,请使用.from_native()
和.to_native()
方法(不适用于Duration
)。此转换是有损的,因为驱动程序的类型支持纳秒精度,而 Python 的原生类型不支持。
驱动程序的时间类型旨在与pytz一起使用。不支持其他datetime.tzinfo 实现(例如,datetime.timezone 、zoneinfo 、dateutil.tz ),并且不太可能正常工作。 |
有关时区缩写的列表,请参阅时区数据库时区列表。
Cypher 类型 | Python 类型 |
---|---|
|
|
|
|
|
|
|
|
|
|
|
|
† 其中tzinfo
不为None
。
†† 其中tzinfo
为None
。
from datetime import datetime
import pytz
from neo4j import GraphDatabase
from neo4j.time import DateTime
URI = "<URI for Neo4j database>"
AUTH = ("<Username>", "<Password>")
friends_since = DateTime(year=1999, month=11, day=23,
hour=7, minute=47, nanosecond=4123)
friends_since = pytz.timezone("US/Eastern").localize(friends_since)
# Python's native datetimes work as well.
# They don't support the full feature-set of Neo4j's type though.
# py_friends_since = datetime(year=1999, month=11, day=23, hour=7, minute=47)
# py_friends_since = pytz.timezone("US/Eastern").localize(py_friends_since)
# Create a friendship with the given DateTime, and return the DateTime
with GraphDatabase.driver(URI, auth=AUTH) as driver:
records, summary, keys = driver.execute_query("""
MERGE (a:Person {name: $name})
MERGE (b:Person {name: $friend})
MERGE (a)-[friendship:KNOWS {since: $friends_since}]->(b)
RETURN friendship.since
""", name="Alice", friend="Bob",
friends_since=friends_since # or friends_since=py_friends_since
)
out_datetime = records[0]["friendship.since"]
print(out_datetime) # 1999-11-23T07:47:00.000004123-05:00
# Converting DateTime to native datetime (lossy)
py_out_datetime = out_datetime.to_native() # type: datetime
print(py_out_datetime) # 1999-11-23 07:47:00.000004-05:00
有关完整文档,请参阅 API 文档 - 时间数据类型。
Date
表示捕获日期的瞬间,但不捕获时间或时区。
from neo4j.time import Date
d = Date(year=2021, month=11, day=2)
print(d) # '2021-11-02'
有关完整文档,请参阅 API 文档 - 时间数据类型 - Date。
Time
表示捕获时间和时区偏移量(以秒为单位)的瞬间,但不捕获日期。
from neo4j.time import Time
import pytz
t = Time(hour=7, minute=47, nanosecond=4123, tzinfo=pytz.FixedOffset(-240))
print(t) # '07:47:00.000004123-04:00'
有关完整文档,请参阅 API 文档 - 时间数据类型 - Time。
LocalTime
表示捕获一天中的时间的瞬间,但不捕获日期或时区。
from neo4j.time import Time
t = Time(hour=7, minute=47, nanosecond=4123)
print(t) # '07:47:00.000004123'
有关完整文档,请参阅 API 文档 - 时间数据类型 - Time。
DateTime
表示捕获日期、时间和时区标识符的瞬间。
from neo4j.time import DateTime
import pytz
dt = DateTime(year=2021, month=11, day=2, hour=7, minute=47, nanosecond=4123)
dt = pytz.timezone("US/Eastern").localize(dt) # time zone localization (optional)
print(dt) # '2021-11-02T07:47:00.000004123-04:00'
有关完整文档,请参阅 API 文档 - 时间数据类型 - DateTime。
LocalDateTime
表示捕获日期和时间的瞬间,但不捕获时区。
from neo4j.time import DateTime
dt = DateTime(year=2021, month=11, day=2, hour=7, minute=47, nanosecond=4123)
print(dt) # '2021-11-02T07:47:00.000004123'
有关完整文档,请参阅 API 文档 - 时间数据类型 - DateTime。
Duration
表示两个时间点之间的差异。作为参数传递的datetime.timedelta
对象将始终隐式转换为neo4j.time.Duration
。无法从neo4j.time.Duration
转换为datetime.timedelta
(因为datetime.timedelta
缺少月支持)。
from neo4j.time import Duration
duration = Duration(years=1, days=2, seconds=3, nanoseconds=4)
print(duration) # 'P1Y2DT3.000000004S'
有关完整文档,请参阅 API 文档 - 时间数据类型 - Duration。
空间类型
Cypher 支持空间值(点),Neo4j 可以将这些点值存储为节点和关系上的属性。
对象属性srid
(空间参考标识符的缩写)是一个数字,用于标识空间类型要解释到的坐标系。您可以将其视为每个空间类型的唯一标识符。
Cypher 类型 | Python 类型 |
---|---|
|
|
|
|
|
|
有关完整文档,请参阅 API 文档 - 空间类型。
CartesianPoint
表示 2D/3D 笛卡尔空间中的一个点。
公开属性x
、y
、z
(后者仅适用于 3D 点)。
from neo4j.spatial import CartesianPoint
# A 2D CartesianPoint
point = CartesianPoint((1.23, 4.56))
print(point.x, point.y, point.srid)
# 1.23 4.56 7203
# A 3D CartesianPoint
point = CartesianPoint((1.23, 4.56, 7.89))
print(point.x, point.y, point.z, point.srid)
# 1.23 4.56 7.8 9157
有关完整文档,请参阅 API 文档 - 空间类型 - CartesianPoint。
WGS84Point
表示世界大地测量系统 (WGS84) 中的一个点。
公开属性longitude
、latitude
、height
(后者仅适用于 3D 点),它们是x
、y
、z
的别名。
from neo4j.spatial import WGS84Point
# A 2D WGS84Point
point = WGS84Point((1.23, 4.56))
print(point.longitude, point.latitude, point.srid)
# or print(point.x, point.y, point.srid)
# 1.23 4.56 4326
# A 3D WGS84Point
point = WGS84Point((1.23, 4.56, 7.89))
print(point.longitude, point.latitude, point.height, point.srid)
# or print(point.x, point.y, point.z, point.srid)
# 1.23 4.56 7.89 4979
有关完整文档,请参阅 API 文档 - 空间类型 - WSG84Point。
图形类型
图形类型仅作为结果传递,不能用作参数。操作查询结果 - 转换为图形部分包含图形类型的示例。
Cypher 类型 | Python 类型 |
---|---|
|
|
|
|
|
|
有关完整文档,请参阅 API 文档 - 图形类型。
Node
表示图中的一个节点。
属性element_id
为实体提供了一个标识符。应谨慎使用此属性,因为不保证单个事务范围之外的 id 值和元素之间的映射。换句话说,使用element_id
跨不同事务MATCH
元素存在风险。
from neo4j import GraphDatabase
URI = "<URI for Neo4j database>"
AUTH = ("<Username>", "<Password>")
with GraphDatabase.driver(URI, auth=AUTH) as driver:
records, _, _ = driver.execute_query(
"MERGE (p:Person {name: $name}) RETURN p AS person",
name="Alice",
database_="neo4j",
)
for record in records:
node = record["person"]
print(f"Node ID: {node.element_id}\n"
f"Labels: {node.labels}\n"
f"Properties: {node.items()}\n"
)
# Node ID: 4:73e9a61b-b501-476d-ad6f-8d7edf459251:0
# Labels: frozenset({'Person'})
# Properties: dict_items([('name', 'Alice')])
有关完整文档,请参阅 API 文档 - 图形类型 - Node。
Relationship
表示图中的一个关系。
属性element_id
为实体提供了一个标识符。应谨慎使用此属性,因为不保证单个事务范围之外的 id 值和元素之间的映射。
from neo4j import GraphDatabase
URI = "<URI for Neo4j database>"
AUTH = ("<Username>", "<Password>")
with GraphDatabase.driver(URI, auth=AUTH) as driver:
records, _, _ = driver.execute_query("""
MERGE (p:Person {name: $name})
MERGE (p)-[r:KNOWS {status: $status, since: date()}]->(friend:Person {name: $friend_name})
RETURN r AS friendship
""", name="Alice", status="BFF", friend_name="Bob",
)
for record in records:
relationship = record["friendship"]
print(f"Relationship ID: {relationship.element_id}\n"
f"Start node: {relationship.start_node}\n"
f"End node: {relationship.end_node}\n"
f"Type: {relationship.type}\n"
f"Friends since: {relationship.get('since')}\n"
f"All properties: {relationship.items()}\n"
)
# Relationship ID: 5:73e9a61b-b501-476d-ad6f-8d7edf459251:1
# Start node: <Node element_id='4:73e9a61b-b501-476d-ad6f-8d7edf459251:0' labels=frozenset({'Person'}) properties={'name': 'Alice'}>
# End node: <Node element_id='4:73e9a61b-b501-476d-ad6f-8d7edf459251:2' labels=frozenset({'Person'}) properties={'name': 'Bob'}>
# Type: KNOWS
# Friends since: 2022-11-07
# All properties: dict_items([('since', neo4j.time.Date(2022, 11, 7)), ('status', 'BFF')])
有关完整文档,请参阅 API 文档 - 图形类型 - Relationship。
Path
表示图中的一个路径。
from neo4j import GraphDatabase
from neo4j.time import Date
URI = "<URI for Neo4j database>"
AUTH = ("<Username>", "<Password>")
def add_friend(driver, name, status, date, friend_name):
driver.execute_query("""
MERGE (p:Person {name: $name})
MERGE (p)-[r:KNOWS {status: $status, since: $date}]->(friend:Person {name: $friend_name})
""", name=name, status=status, date=date, friend_name=friend_name,
database_="neo4j",
)
with GraphDatabase.driver(URI, auth=AUTH) as driver:
# Create some :Person nodes linked by :KNOWS relationships
add_friend(driver, name="Alice", status="BFF", date=Date.today(), friend_name="Bob")
add_friend(driver, name="Bob", status="Fiends", date=Date.today(), friend_name="Sofia")
add_friend(driver, name="Sofia", status="Acquaintances", date=Date.today(), friend_name="Sofia")
# Follow :KNOWS relationships outgoing from Alice three times, return as path
records, _, _ = driver.execute_query("""
MATCH path=(:Person {name: $name})-[:KNOWS*3]->(:Person)
RETURN path AS friendship_chain
""", name="Alice",
database_="neo4j",
)
path = records[0]["friendship_chain"]
print("-- Path breakdown --")
for friendship in path:
print("{name} is friends with {friend} ({status})".format(
name=friendship.start_node.get("name"),
friend=friendship.end_node.get("name"),
status=friendship.get("status"),
))
有关完整文档,请参阅 API 文档 - 图形类型 - Path。
扩展类型
驱动程序支持更多类型的查询参数,这些参数将自动映射到核心类型之一。由于此转换,并且服务器对扩展类型一无所知,因此驱动程序永远不会在结果中返回这些类型,而始终返回其相应的映射。
参数类型 | 映射的 Python 类型 |
---|---|
tuple |
|
bytearray |
|
numpy |
|
pandas |
|
pandas |
|
pandas |
|
通常,如果您不确定给定参数上将发生的类型转换,您可以像以下示例中那样进行测试
import neo4j
with neo4j.GraphDatabase.driver(URI, auth=AUTH) as driver:
type_in = ("foo", "bar")
records, _, _ = driver.execute_query("RETURN $x AS type_out", x=type_in)
type_out = records[0].get("type_out")
print(type(type_out)) # <class 'list'>
print(type_out) # ['foo', 'bar']
异常
分类 | 描述 |
---|---|
|
Neo4j 服务器报告的错误(例如,错误的 Cypher 语法、连接错误、错误的凭据等) |
|
驱动程序报告的错误(例如,参数或事务的错误使用、结果的错误处理等) |
某些服务器错误被标记为可以安全重试,无需更改原始请求。此类错误的示例包括死锁、内存问题或连接问题。所有驱动程序的异常类型都实现了.is_retryable()
方法,该方法提供了有关进一步尝试是否可能成功的见解。这在显式事务中运行查询时特别有用,以了解失败的查询是否值得重新运行。
词汇表
- LTS
-
长期支持版本是保证支持若干年的版本。Neo4j 4.4 是 LTS,Neo4j 5 也将有一个 LTS 版本。
- Aura
-
Aura 是 Neo4j 的完全托管云服务。它提供免费和付费计划。
- Cypher
-
Cypher 是 Neo4j 的图查询语言,允许您从数据库中检索数据。它类似于 SQL,但适用于图。
- APOC
-
Awesome Procedures On Cypher (APOC) 是一个函数库(包含许多函数),这些函数无法用 Cypher 本身轻松表达。
- Bolt
-
Bolt 是 Neo4j 实例与驱动程序之间交互使用的协议。默认情况下,它监听 7687 端口。
- ACID
-
原子性、一致性、隔离性、持久性 (ACID) 是保证数据库事务可靠处理的特性。符合 ACID 的 DBMS 确保数据库中的数据即使在发生故障的情况下也能保持准确和一致。
- 最终一致性
-
如果数据库保证所有集群成员将在某个时间点存储数据的最新版本,则该数据库最终一致。
- 因果一致性
-
如果读取和写入查询以相同的顺序由集群中的每个成员看到,则数据库具有因果一致性。这比最终一致性更强。
- NULL
-
空标记不是一种类型,而是值不存在的占位符。有关更多信息,请参阅 Cypher → 使用
null
。 - 事务
-
事务是工作的单元,要么完全提交,要么在发生故障时回滚。例如银行转账:它涉及多个步骤,但它们必须全部成功或被撤销,以避免从一个账户中扣款但未添加到另一个账户中。
- 背压
-
背压是阻碍数据流动的力量。它确保客户端不会被超出其处理能力的数据所淹没。
- 事务函数
-
事务函数是由
execute_read
或execute_write
调用执行的回调函数。如果服务器发生故障,驱动程序会自动重新执行回调函数。 - 驱动程序
-
一个
Driver
对象包含建立与 Neo4j 数据库连接所需的详细信息。