尝试将数据传输到 arangodb 时数据会混淆
Data gets mixed up while trying to transfer it to arangodb
我正在尝试转移 ca。 10GB 的 json 数据(在我的例子中是推文)到 arangodb 中的一个集合。我也在尝试使用 joblib:
from ArangoConn import ArangoConn
import Userdata as U
import encodings
from joblib import Parallel,delayed
import json
from glob import glob
import time
def progress(total, prog, start, stri = ""):
if(prog == 0):
print("")
prog = 1;
perc = prog / total
diff = time.time() - start
rem = (diff / prog) * (total - prog)
bar = ""
for i in range(0,int(perc*20)):
bar = bar + "|"
for i in range(int(perc*20),20):
bar = bar + " "
print("\r"+"progress: " + "[" + bar + "] " + str(prog) + " of " +
str(total) + ": {0:.1f}% ".format(perc * 100) + "- " +
time.strftime("%H:%M:%S", time.gmtime(rem)) + " " + stri, end="")
def processfile(filepath):
file = open(filepath,encoding='utf-8')
s = file.read()
file.close()
data = json.loads(s)
Parallel(n_jobs=12, verbose=0, backend="threading"
(map(delayed(ArangoConn.createDocFromObject), data))
files = glob(U.path+'/*.json')
i = 1
j = len(files)
starttime = time.time()
for f in files:
progress(j,i,starttime,f)
i = i+1
processfile(f)
和
from pyArango.connection import Connection
import Userdata as U
import time
class ArangoConn:
def __init__(self,server,user,pw,db,collectionname):
self.server = server
self.user = user
self.pw = pw
self.db = db
self.collectionname = collectionname
self.connection = None
self.dbHandle = self.connect()
if not self.dbHandle.hasCollection(name=self.collectionname):
coll = self.dbHandle.createCollection(name=collectionname)
else:
coll = self.dbHandle.collections[collectionname]
self.collection = coll
def db_createDocFromObject(self, obj):
data = obj.__dict__()
doc = self.collection.createDocument()
for key,value in data.items():
doc[key] = value
doc._key= str(int(round(time.time() * 1000)))
doc.save()
def connect(self):
self.connection = Connection(arangoURL=self.server + ":8529",
username=self.user, password=self.pw)
if not self.connection.hasDatabase(self.db):
db = self.connection.createDatabase(name=self.db)
else:
db = self.connection.databases.get(self.db)
return db
def disconnect(self):
self.connection.disconnectSession()
def getAllData(self):
docs = []
for doc in self.collection.fetchAll():
docs.append(self.doc_to_result(doc))
return docs
def addData(self,obj):
self.db_createDocFromObject(obj)
def search(self,collection,search,prop):
docs = []
aql = """FOR q IN """+collection+""" FILTER q."""+prop+""" LIKE
"%"""+search+"""%" RETURN q"""
results = self.dbHandle.AQLQuery(aql, rawResults=False, batchSize=1)
for doc in results:
docs.append(self.doc_to_result(doc))
return docs
def doc_to_result(self,arangodoc):
modstore = arangodoc.getStore()
modstore["_key"] = arangodoc._key
return modstore
def db_createDocFromJson(self,json):
for d in json:
doc = self.collection.createDocument()
for key,value in d.items():
doc[key] = value
doc._key = str(int(round(time.time() * 1000)))
doc.save()
@staticmethod
def createDocFromObject(obj):
c = ArangoConn(U.url, U.user, U.pw, U.db, U.collection)
data = obj
doc = c.collection.createDocument()
for key, value in data.items():
doc[key] = value
doc._key = doc["id"]
doc.save()
c.connection.disconnectSession()
有点像那样。我的问题是登陆数据库的数据不知何故混淆了。
如您在屏幕截图中所见,"id" 和 "id_str" 并不相同 - 它们应该是相同的。
到目前为止我调查了什么:
我认为在某些时候数据库中的默认键可能 "collide"
因为线程,所以我将密钥设置为推文 ID。
我试过不用多线程的。线程似乎不是
问题
我查看了我发送到数据库的数据...一切似乎都很好
但是一旦我与数据库通信,数据就会混淆。
我的教授认为 pyarango 中的某些东西可能不是线程安全的,它会弄乱数据,但我不这么认为,因为线程似乎不是问题所在。
我不知道这种行为可能来自哪里......
有什么想法吗?
屏幕截图显示以下值:
id : 892886691937214500
id_str : 892886691937214465
看起来值在某个地方被转换为 IEEE754 double,它不能安全地表示后一个值。因此,转换可能会导致一些精度损失。
node.js 中的一个简单示例(JavaScript 对任何大于 0xffffffff 的数值使用 IEEE754 双精度数)表明这可能是问题原因:
$ node
> 892886691937214500
892886691937214500
> 892886691937214465
892886691937214500
所以问题是转换发生在哪里。你能检查 python 客户端程序是否正确地将预期值发送到 ArangoDB,或者它是否已经发送了 converted/truncated 值?
一般来说,任何超过 0x7fffffffffffffff 的整数在存储到 ArangoDB 时都会被截断,或者转换为 IEEE754 double。这可以通过将数字值存储在字符串中来避免,但是当然比较两个数字字符串会产生与比较两个数字不同的结果(例如 "10" < "9"
与 10 > 9
)。
我正在尝试转移 ca。 10GB 的 json 数据(在我的例子中是推文)到 arangodb 中的一个集合。我也在尝试使用 joblib:
from ArangoConn import ArangoConn
import Userdata as U
import encodings
from joblib import Parallel,delayed
import json
from glob import glob
import time
def progress(total, prog, start, stri = ""):
if(prog == 0):
print("")
prog = 1;
perc = prog / total
diff = time.time() - start
rem = (diff / prog) * (total - prog)
bar = ""
for i in range(0,int(perc*20)):
bar = bar + "|"
for i in range(int(perc*20),20):
bar = bar + " "
print("\r"+"progress: " + "[" + bar + "] " + str(prog) + " of " +
str(total) + ": {0:.1f}% ".format(perc * 100) + "- " +
time.strftime("%H:%M:%S", time.gmtime(rem)) + " " + stri, end="")
def processfile(filepath):
file = open(filepath,encoding='utf-8')
s = file.read()
file.close()
data = json.loads(s)
Parallel(n_jobs=12, verbose=0, backend="threading"
(map(delayed(ArangoConn.createDocFromObject), data))
files = glob(U.path+'/*.json')
i = 1
j = len(files)
starttime = time.time()
for f in files:
progress(j,i,starttime,f)
i = i+1
processfile(f)
和
from pyArango.connection import Connection
import Userdata as U
import time
class ArangoConn:
def __init__(self,server,user,pw,db,collectionname):
self.server = server
self.user = user
self.pw = pw
self.db = db
self.collectionname = collectionname
self.connection = None
self.dbHandle = self.connect()
if not self.dbHandle.hasCollection(name=self.collectionname):
coll = self.dbHandle.createCollection(name=collectionname)
else:
coll = self.dbHandle.collections[collectionname]
self.collection = coll
def db_createDocFromObject(self, obj):
data = obj.__dict__()
doc = self.collection.createDocument()
for key,value in data.items():
doc[key] = value
doc._key= str(int(round(time.time() * 1000)))
doc.save()
def connect(self):
self.connection = Connection(arangoURL=self.server + ":8529",
username=self.user, password=self.pw)
if not self.connection.hasDatabase(self.db):
db = self.connection.createDatabase(name=self.db)
else:
db = self.connection.databases.get(self.db)
return db
def disconnect(self):
self.connection.disconnectSession()
def getAllData(self):
docs = []
for doc in self.collection.fetchAll():
docs.append(self.doc_to_result(doc))
return docs
def addData(self,obj):
self.db_createDocFromObject(obj)
def search(self,collection,search,prop):
docs = []
aql = """FOR q IN """+collection+""" FILTER q."""+prop+""" LIKE
"%"""+search+"""%" RETURN q"""
results = self.dbHandle.AQLQuery(aql, rawResults=False, batchSize=1)
for doc in results:
docs.append(self.doc_to_result(doc))
return docs
def doc_to_result(self,arangodoc):
modstore = arangodoc.getStore()
modstore["_key"] = arangodoc._key
return modstore
def db_createDocFromJson(self,json):
for d in json:
doc = self.collection.createDocument()
for key,value in d.items():
doc[key] = value
doc._key = str(int(round(time.time() * 1000)))
doc.save()
@staticmethod
def createDocFromObject(obj):
c = ArangoConn(U.url, U.user, U.pw, U.db, U.collection)
data = obj
doc = c.collection.createDocument()
for key, value in data.items():
doc[key] = value
doc._key = doc["id"]
doc.save()
c.connection.disconnectSession()
有点像那样。我的问题是登陆数据库的数据不知何故混淆了。
如您在屏幕截图中所见,"id" 和 "id_str" 并不相同 - 它们应该是相同的。
到目前为止我调查了什么:
我认为在某些时候数据库中的默认键可能 "collide" 因为线程,所以我将密钥设置为推文 ID。
我试过不用多线程的。线程似乎不是 问题
我查看了我发送到数据库的数据...一切似乎都很好
但是一旦我与数据库通信,数据就会混淆。
我的教授认为 pyarango 中的某些东西可能不是线程安全的,它会弄乱数据,但我不这么认为,因为线程似乎不是问题所在。
我不知道这种行为可能来自哪里...... 有什么想法吗?
屏幕截图显示以下值:
id : 892886691937214500
id_str : 892886691937214465
看起来值在某个地方被转换为 IEEE754 double,它不能安全地表示后一个值。因此,转换可能会导致一些精度损失。
node.js 中的一个简单示例(JavaScript 对任何大于 0xffffffff 的数值使用 IEEE754 双精度数)表明这可能是问题原因:
$ node
> 892886691937214500
892886691937214500
> 892886691937214465
892886691937214500
所以问题是转换发生在哪里。你能检查 python 客户端程序是否正确地将预期值发送到 ArangoDB,或者它是否已经发送了 converted/truncated 值?
一般来说,任何超过 0x7fffffffffffffff 的整数在存储到 ArangoDB 时都会被截断,或者转换为 IEEE754 double。这可以通过将数字值存储在字符串中来避免,但是当然比较两个数字字符串会产生与比较两个数字不同的结果(例如 "10" < "9"
与 10 > 9
)。