Changeset: 82f853e42e8e for MonetDB URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=82f853e42e8e Added Files: tools/embeddedpy/Tests/pylite07.py tools/embeddedpy/Tests/pylite07.stable.err tools/embeddedpy/Tests/pylite07.stable.out tools/embeddedpy/Tests/pylite08.py tools/embeddedpy/Tests/pylite08.stable.err tools/embeddedpy/Tests/pylite08.stable.out Modified Files: tools/embeddedpy/Tests/All tools/embeddedpy/Tests/pylite06.py tools/embeddedpy/Tests/pylite06.stable.out tools/embeddedpy/embeddedpy.c tools/embeddedpy/setup.py Branch: pyapi Log Message:
Added support for creating/inserting tables from PyDict objects in MonetDBLite, and added testcases. diffs (truncated from 643 to 300 lines): diff --git a/tools/embeddedpy/Tests/All b/tools/embeddedpy/Tests/All --- a/tools/embeddedpy/Tests/All +++ b/tools/embeddedpy/Tests/All @@ -6,3 +6,6 @@ HAVE_LIBPY?pylite03 HAVE_LIBPY?pylite04 HAVE_LIBPY?pylite05 HAVE_LIBPY?pylite06 +HAVE_LIBPY?pylite07 +HAVE_LIBPY?pylite08 + diff --git a/tools/embeddedpy/Tests/pylite06.py b/tools/embeddedpy/Tests/pylite06.py --- a/tools/embeddedpy/Tests/pylite06.py +++ b/tools/embeddedpy/Tests/pylite06.py @@ -19,6 +19,15 @@ def query(conn): # do a query that takes a reasonable amount of time in the database, as time in the database is the only thing that is parallelized monetdblite.sql('select j,k from pylite06a inner join pylite06b on pylite06a.i=pylite06b.i', conn) +#sequential + +start = time.time() +for n in range(10): + query(default_conn) +end = time.time() + +sequential_time = end - start + # test threading with every thread using the same client (only one SQL transaction per client, so the threads don't do much) start = time.time() threads = [] @@ -36,7 +45,7 @@ same_client_time = end - start del default_conn start = time.time() -# test threading with different clients (every client can have its own SQL transaction) +# test threading with different clients (every client has its own SQL transaction) threads = [] for n in range(10): thread = threading.Thread(target=query, args=[monetdblite.connect()]) @@ -49,7 +58,21 @@ end = time.time() different_client_time = end - start -if different_client_time > same_client_time: - print "Same client is faster" -else: print "Different client is faster" +# Time-wise, we expect Different Clients > Same Client > Sequential +# Same Client and Sequential should be close, because the actual query is not parallelized when the same client is used +# Same Client is slightly faster because there is a little bit of work the other threads can do while the GIL is released during the query +# but since the bulk of the work is in the query, this does not make a huge difference +# Different Clients completely parallelize the query as well, and since the bulk of the work is in the query this should be the fastest by far +# we print the ranking instead of actual times because Mtest.py requires the same output when run multiple times +# and measured times will differ for each run/for every machine, but rankings should not differ (unless run on a 1 core machine) +a = [('Threads + Different Clients', different_client_time), ('Threads + Same Client', same_client_time), ('Sequential (No Threads)', sequential_time)] +a = sorted(a, key=lambda x : x[1]) +print 'Rankings (Fastest to Slowest)' +for i in range(len(a)): + print '%d: %s' % (i + 1, a[i][0]) + +#print "Sequential", sequential_time +#print "Same", same_client_time +#print "Different", different_client_time + diff --git a/tools/embeddedpy/Tests/pylite06.stable.out b/tools/embeddedpy/Tests/pylite06.stable.out --- a/tools/embeddedpy/Tests/pylite06.stable.out +++ b/tools/embeddedpy/Tests/pylite06.stable.out @@ -6,7 +6,10 @@ stdout of test 'pylite06` in directory ' # 17:47:59 > Making directory /tmp/pylite_dbfarm -Different client is faster +Rankings (Fastest to Slowest) +1: Threads + Different Clients +2: Threads + Same Client +3: Sequential (No Threads) # 17:48:01 > # 17:48:01 > "Done." diff --git a/tools/embeddedpy/Tests/pylite07.py b/tools/embeddedpy/Tests/pylite07.py new file mode 100644 --- /dev/null +++ b/tools/embeddedpy/Tests/pylite07.py @@ -0,0 +1,40 @@ + +# test inserting dictionaries + +import monetdblite, shutil, os +dbfarm = '/tmp/pylite_dbfarm' +if os.path.isdir(dbfarm): shutil.rmtree(dbfarm) +monetdblite.init(dbfarm) + +import numpy + +# create table using dict +a = dict() +numpy.random.seed(33) +a['i'] = numpy.random.randint(0, 1000, 100000) +a['j'] = numpy.random.randint(0, 1000, 100000) +a['k'] = numpy.random.randint(0, 1000, 100000) +a['l'] = numpy.random.randint(0, 1000, 100000) +a['m'] = numpy.random.randint(0, 1000, 100000) + +monetdblite.create('pylite07', a) +arr = monetdblite.sql('select * from pylite07') +print arr +print len(arr['i']) + +# create empty table +monetdblite.create('pylite07a', colnames=['a', 'b', 'c', 'd', 'e' , 'f'], values=[[],[],[],[],[],[]]) +# insert data using dictionary +b = dict() +b['a'] = numpy.random.randint(0, 1000, 100000) +b['b'] = numpy.random.randint(0, 1000, 100000) +b['c'] = numpy.random.randint(0, 1000, 100000) +b['d'] = numpy.random.randint(0, 1000, 100000) +b['e'] = numpy.random.randint(0, 1000, 100000) +b['f'] = numpy.random.randint(0, 1000, 100000) + +monetdblite.insert('pylite07a', b) +arr = monetdblite.sql('select * from pylite07a') +print arr +print len(arr['a']) + diff --git a/tools/embeddedpy/Tests/pylite07.stable.err b/tools/embeddedpy/Tests/pylite07.stable.err new file mode 100644 --- /dev/null +++ b/tools/embeddedpy/Tests/pylite07.stable.err @@ -0,0 +1,12 @@ +stderr of test 'pylite07` in directory 'tools/embeddedpy` itself: + + +# 14:37:40 > +# 14:37:40 > "/usr/bin/python2" "pylite07.py" "pylite07" +# 14:37:40 > + + +# 14:37:41 > +# 14:37:41 > "Done." +# 14:37:41 > + diff --git a/tools/embeddedpy/Tests/pylite07.stable.out b/tools/embeddedpy/Tests/pylite07.stable.out new file mode 100644 --- /dev/null +++ b/tools/embeddedpy/Tests/pylite07.stable.out @@ -0,0 +1,17 @@ +stdout of test 'pylite07` in directory 'tools/embeddedpy` itself: + + +# 14:37:40 > +# 14:37:40 > "/usr/bin/python2" "pylite07.py" "pylite07" +# 14:37:40 > + +Making directory /tmp/pylite_dbfarm +{'i': array([ 20, 391, 728, ..., 738, 931, 115]), 'k': array([869, 249, 127, ..., 121, 72, 893]), 'j': array([358, 699, 378, ..., 985, 651, 570]), 'm': array([104, 179, 579, ..., 865, 274, 363]), 'l': array([211, 139, 223, ..., 660, 283, 48])} +100000 +{'a': array([ 822., 768., 519., ..., 81., 96., 398.]), 'c': array([ 627., 504., 561., ..., 279., 341., 45.]), 'b': array([ 881., 502., 524., ..., 322., 297., 265.]), 'e': array([ 279., 331., 112., ..., 171., 384., 554.]), 'd': array([ 202., 523., 667., ..., 541., 949., 604.]), 'f': array([ 336., 690., 134., ..., 47., 273., 98.])} +100000 + +# 14:37:41 > +# 14:37:41 > "Done." +# 14:37:41 > + diff --git a/tools/embeddedpy/Tests/pylite08.py b/tools/embeddedpy/Tests/pylite08.py new file mode 100644 --- /dev/null +++ b/tools/embeddedpy/Tests/pylite08.py @@ -0,0 +1,65 @@ +# test error statements + +import monetdblite, shutil, os +dbfarm = '/tmp/pylite_dbfarm' +if os.path.isdir(dbfarm): shutil.rmtree(dbfarm) + +import sys +print '\n--select before init--' +try: monetdblite.sql('select * from tables') +except: print str(sys.exc_info()[1]) + +print '\n--init with weird argument--' +try: monetdblite.init(33) +except: print str(sys.exc_info()[1]) + +print '\n--init in unwritable directory--' +try: monetdblite.init('/unwritabledir') +except: print str(sys.exc_info()[1]) + +print '\n--proper init--' +monetdblite.init(dbfarm) + +print '\n--select from non-existent table--' +try: monetdblite.sql('select * from nonexistenttable') +except: print str(sys.exc_info()[1]) + +print '\n--invalid connection object--' +try: monetdblite.sql('select * from tables', conn=33) +except: print str(sys.exc_info()[1]) + +print '\n--no colnames with list--' +try: monetdblite.create('pylite08', values=[[]]) +except: print str(sys.exc_info()[1]) + +print '\n--invalid colnames--' +try: monetdblite.create('pylite08', values=[[]], colnames=33) +except: print str(sys.exc_info()[1]) + +print '\n--empty colnames--' +try: monetdblite.create('pylite08', values=[[]], colnames=[]) +except: print str(sys.exc_info()[1]) + +print '\n--too many colnames for values--' +try: monetdblite.create('pylite08', values=[[]], colnames=['a', 'b', 'c']) +except: print str(sys.exc_info()[1]) + +print '\n--too few colnames for values--' +try: monetdblite.create('pylite08', values=[[33], [44], [55]], colnames=['a']) +except: print str(sys.exc_info()[1]) + +print '\n--dictionary with invalid keys--' +d = dict() +d[33] = 44 +try: monetdblite.create('pylite08', d) +except: print str(sys.exc_info()[1]) + +monetdblite.create('pylite08', dict(a=[],b=[],c=[])) + +print '\n--missing dict key in insert--' +try: monetdblite.insert('pylite08', dict(a=33,b=44)) +except: print str(sys.exc_info()[1]) + +print '\n--too few columns in insert--' +try: monetdblite.insert('pylite08', [[33],[44]]) +except: print str(sys.exc_info()[1]) diff --git a/tools/embeddedpy/Tests/pylite08.stable.err b/tools/embeddedpy/Tests/pylite08.stable.err new file mode 100644 --- /dev/null +++ b/tools/embeddedpy/Tests/pylite08.stable.err @@ -0,0 +1,13 @@ +stderr of test 'pylite08` in directory 'tools/embeddedpy` itself: + + +# 14:37:41 > +# 14:37:41 > "/usr/bin/python2" "pylite08.py" "pylite08" +# 14:37:41 > + +#GDKcreatedir(/tmp/pylite_dbfarm) + +# 14:37:42 > +# 14:37:42 > "Done." +# 14:37:42 > + diff --git a/tools/embeddedpy/Tests/pylite08.stable.out b/tools/embeddedpy/Tests/pylite08.stable.out new file mode 100644 --- /dev/null +++ b/tools/embeddedpy/Tests/pylite08.stable.out @@ -0,0 +1,55 @@ +stdout of test 'pylite08` in directory 'tools/embeddedpy` itself: + + +# 14:37:41 > +# 14:37:41 > "/usr/bin/python2" "pylite08.py" "pylite08" +# 14:37:41 > + + +--select before init-- +monetdb has not been initialized yet + +--init with weird argument-- +Expected a directory name as an argument. + +--init in unwritable directory-- +Making directory /unwritabledir +Failed to initialize MonetDB. GDKfatal() with unspecified error? + +--proper init-- +Making directory /tmp/pylite_dbfarm + +--select from non-existent table-- +SQL Query Failed: ParseException:SQLparser:42S02!SELECT: no such table 'nonexistenttable' + +--invalid connection object-- +conn must be a connection object created by monetdblite.connect(). + +--no colnames with list-- +no colnames are specified and values is not a dict + +--invalid colnames-- +colnames must be a list + +--empty colnames-- +colnames must have at least one element + +--too many colnames for values-- +MALException:pyapi.eval:An array of size 1 was returned, yet we expect a list of 3 columns. The result is invalid. + +--too few colnames for values-- +MALException:pyapi.eval:An array of size 3 was returned, yet we expect a list of 1 columns. The result is invalid. + +--dictionary with invalid keys-- +expected a key of type 'str', but key was of type int + _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list