Neo4j 第十二篇:使用Python驅動訪問Neo4j


neo4j官方驅動支持Python語言,驅動程序主要包含Driver類型和Session類型。Driver對象包含Neo4j數據庫的詳細信息,包括主機url、安全驗證等配置,還管理着連接池(Connection Pool);Session對象是執行事務單元的邏輯上下文,事務是在Session的上下文中執行的。由於Session不是線程安全的,並能夠從Driver對象管理的連接池中回收利用(Recycle)連接,因此,Session對象是輕量級的(lightweight),用完之后應立即銷毀(disposable)。

Driver對象和Session對象的關系是:Driver對象負責管理連接池,從連接池中分配連接創建Session對象;Session對象在單個線程中接收Cypher和啟動事務,在事務執行完成之后,立即銷毀Session對象;Driver對象負責回收連接,等待為下一個Session對象分配連接。

一,安裝Python版本的Neo4j驅動

如果不關注驅動的版本,可以安裝最新版本的Python驅動

pip install neo4j-driver

也可以在pip命令中指定python驅動的版本:

pip install neo4j-driver==$PYTHON_DRIVER_VERSION
pip install neo4j-driver==1.4.0

二,Driver對象

在安裝neo4j驅動之后,在python代碼中導入GraphDatabase模塊,用於查詢和更新圖數據庫:

from neo4j.v1 import GraphDatabase

1,創建Driver對象實例

輸入neo4j數據庫的uri,用戶的安全驗證,實例化Driver對象,並創建連接池:

from neo4j.v1 import GraphDatabase
uri = "bolt://localhost:7687"
_driver = GraphDatabase.driver(uri, auth=("neo4j", "password"))

使用close()函數關閉Driver對象分配的任何連接:

_driver.close()

2,使用Driver對象來創建Session對象

Driver對象從連接池中分配連接,創建Session對象:

_session = _driver.session()

三,Session對象

Session的創建是一個輕量級的操作,由於Session不是線程安全的,因此,Session通常應該在單個線程中短暫存續,用完之后立即銷毀。在Python中,推薦在with上下文中創建和銷毀Session對象:

def add_person(name):
    with _driver.session() as session:
        session.run("CREATE (a:Person {name: $name})", name=name)

Session對象是執行事務的邏輯上下文,Cypher支持兩種方式來提交事務。

1,以自動提交方式提交事務

以自動提交事務的方式執行Cypher查詢,在Session對象執行Cypher語句之后,事務立即提交,因此,一次事務只能執行一個Cyper查詢,返回的結果是StatementResult對象:

_session.run(statement, parameters=None)

2,以事務函數方式來提交事務

事務函數包含事務的工作單元,以事務函數方式提交事務是neo4j推薦的提交事務的方式,在事務函數方式中,一個事務可以執行多個Cypher查詢。

首先,定義事務函數,傳遞相應的參數(Cypher語句和參數):

def create_person_node(tx, name):
    tx.run("CREATE (a:Person {name: $name}) RETURN id(a)", name=name)

然后,在Session對象中啟動寫事務(write_transaction)來調用事務函數,返回的結果是StatementResult對象:

def add_person(driver, name):
    with _driver.session() as session:
        # Caller for transactional unit of work
        return session.write_transaction(create_person_node, name)

三,StatementResult和Record

Session對象執行Cypher查詢的結果是StatementResult類型,該類型實際上是由Record對象構成的集合,該類型的常用函數如下:

  • keys():是由Record集合的Key構成的元組
  • records():是由Record對象構成的集合
  • single():從result變量中獲取下一個記錄,返回值是下一個Record或None
  • peek():從結果中獲取下一個Record對象,而該對象仍然保留在結果緩存中,以便后續進行處理。

Record類型是一個有序的Key/Value對的序列,這意味着,Record對象類似於由Key:Value構成的列表,Key字段的值可以通過字段名稱或索引來訪問:

  • items() :是由元組(key,value)構成的列表
  • keys():是由一個Record對象的key構成的元組
  • values():是由一個Record對象的value構成的元組
  • index(key):返回指定Key在Record對象內的索引

 

附,示例代碼

class BookmarksExample(object):

    def __init__(self, uri, user, password):
        self._driver = GraphDatabase.driver(uri, auth=(user, password))

    def close(self):
        self._driver.close()

    # Create a person node.
    @classmethod
    def create_person(cls, tx, name):
        tx.run("CREATE (:Person {name: $name})", name=name)

    # Create an employment relationship to a pre-existing company node.
    # This relies on the person first having been created.
    @classmethod
    def employ(cls, tx, person_name, company_name):
        tx.run("MATCH (person:Person {name: $person_name}) "
               "MATCH (company:Company {name: $company_name}) "
               "CREATE (person)-[:WORKS_FOR]->(company)",
               person_name=person_name, company_name=company_name)

    # Create a friendship between two people.
    @classmethod
    def create_friendship(cls, tx, name_a, name_b):
        tx.run("MATCH (a:Person {name: $name_a}) "
               "MATCH (b:Person {name: $name_b}) "
               "MERGE (a)-[:KNOWS]->(b)",
               name_a=name_a, name_b=name_b)

    # Match and display all friendships.
    @classmethod
    def print_friendships(cls, tx):
        result = tx.run("MATCH (a)-[:KNOWS]->(b) RETURN a.name, b.name")
        for record in result:
            print("{} knows {}".format(record["a.name"] ,record["b.name"]))

    def main(self):
        saved_bookmarks = []  # To collect the session bookmarks

        # Create the first person and employment relationship.
        with self._driver.session() as session_a:
            session_a.write_transaction(self.create_person, "Alice")
            session_a.write_transaction(self.employ, "Alice", "Wayne Enterprises")
            saved_bookmarks.append(session_a.last_bookmark())

        # Create the second person and employment relationship.
        with self._driver.session() as session_b:
            session_b.write_transaction(self.create_person, "Bob")
            session_b.write_transaction(self.employ, "Bob", "LexCorp")
            saved_bookmarks.append(session_b.last_bookmark())

        # Create a friendship between the two people created above.
        with self._driver.session(bookmarks=saved_bookmarks) as session_c:
            session_c.write_transaction(self.create_friendship, "Alice", "Bob")
            session_c.read_transaction(self.print_friendships)



class Neo4jProvider:

    def __init__(self, uri, user, password):
        self._driver = GraphDatabase.driver(uri, auth=(user, password))

    def close(self):
        self._driver.close()

    def add_greeting_node(self, message):
        with self._driver.session() as session:
            session.write_transaction(self._create_greeting, message)

    @staticmethod
    def _create_greeting(tx, message):
        tx.run("CREATE (a:Greeting) SET a.message = $message ", message=message)
View Code

 

 

參考文檔:

Neo4j Bolt Driver for Python

Sessions and transactions


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM