我使用Django和Neo4j以及neomodel作为OGM(图的ORM)。它运行得很好,但在测试方面,Neomodel不支持关系数据库中常见的Django行为。我的意思是,它不会创建一个在测试开始时创建并在测试结束后销毁的临时Neo4j实例。
我一直在做一些研究,发现了两种可能的解决方案:
-
第一步是创建一个自定义发现运行程序,在其中停止开发数据库,然后从另一个路径启动测试数据库,运行测试,最后停止测试实例,重新启动开发实例。该解决方案是在neo4j数据库的线程Django测试中提出的。以下代码已适用于3.1.1 Neo4j版本:
from time import sleep from subprocess import call from django.test.runner import DiscoverRunner from py2neo import authenticate class DiscoverRunner(DiscoverRunner): def setup_databases(self, *args, **kwargs): # Stop your development instance call("sudo neo4j stop", shell=True) # Sleep to ensure the service has completely stopped sleep(1) # Start your test instance (see section below for more details) success = call("neo4j_test/neo4j-community-3.1.1/bin/neo4j" " start", shell=True) # Need to sleep to wait for the test instance to completely come up sleep(10) if success != 0: return False # These lines have been commented because I've set the configuration # dbms.security.auth_enabled=false #try: # # For neo4j 2.2.x you'll need to set a password or deactivate auth # # Nigel Small's py2neo gives us an easy way to accomplish this # # call("source /path/to/virtualenv/bin/activate && " # # "/path/to/virtualenv/bin/neoauth " # # "neo4j neo4j my-p4ssword") # authenticate("localhost:7474", "neo4j", "my-password") #except OSError: # pass # Don't import neomodel until we get here because we need to wait # for the new db to be spawned from neomodel import db # Delete all previous entries in the db prior to running tests query = "match (n)-[r]-() delete n,r" db.cypher_query(query) super(DiscoverRunner, self).__init__(*args, **kwargs) def teardown_databases(self, old_config, **kwargs): from neomodel import db # Delete all previous entries in the db after running tests query = "match (n)-[r]-() delete n,r" db.cypher_query(query) sleep(1) # Shut down test neo4j instance success = call("neo4j_test/neo4j-community-3.1.1/bin/neo4j" " stop", shell=True) if success != 0: return False sleep(1) # start back up development instance call("sudo neo4j start", shell=True)
它可以正常工作,直到它尝试连接到测试数据库并进行查询,因为它使用加密连接并在
'~/.neo4/known_hosts'
中查找连接密钥,但它与开发数据库冲突,并因以下错误而崩溃:neo4j.v1.exceptions.ProtocolError: Server certificate does not match known certificate for 'localhost'; check details in file '~/.neo4j/known_hosts'
那么,有没有办法避免这种认证检查?
-
第二个解决方案是创建相同的发现运行程序,并在Neo4j中设置一个ImpermanentDatabase。问题是,除了python单元测试中的Neo4j ImpermanentDatabase之外,我发现的所有信息都在Java中,但它并没有让我清楚如何在python中实现这一点。有人知道如何在python中使用它吗?
非常感谢。
经过一些研究,我提出了使用第一种方法的解决方案。
Neo4j的官方python驱动程序在连接到驱动程序时有一个可配置的参数(加密):
GraphDatabase.driver('bolt://' + hostname, auth=basic_auth(username, password), encrypted=True)
如果加密参数设置为False,则'~/.neo4/known_hosts'
将被忽略,并且不会出现错误。遗憾的是,新模型框架还不支持该参数的调优,但我已经在github中分叉了存储库,并在全局设置中添加了一个名为ENCRYPTED_CONNECTION的变量,该变量可以被覆盖以实现这一目标。
我正在等待提取请求被接受,我会通知是否被接受。
顺便说一句,如果有人能给我们一些问题中评论的第二种方法的启示,那就太棒了。
谢谢。