Skip to content

Commit

Permalink
Bugfix: handle NULL in data
Browse files Browse the repository at this point in the history
  • Loading branch information
BnMcGn committed Jul 2, 2021
1 parent 3d5bd3d commit 40de3c5
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 23 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ To connect to a postgresql database named cookiejar, you might create a file cja

conn = connect(host="localhost", \
database="cookiejar", \
user="me",
user="me", \
password="totally_unguessable")

You may then edit the ingredients table:
Expand All @@ -36,7 +36,7 @@ If you don't wish to store your totally unguessable password in the python file,

conn = connect(host="localhost", \
database="cookiejar", \
user="me",
user="me", \
password=getpass())

# Author
Expand Down
62 changes: 41 additions & 21 deletions src/vibase.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@

from src.util import query_yes_no, query_options


def extract_conn_from_module(module):
for x in module.__dict__.values():
if hasattr(x, "cursor"):
Expand All @@ -22,7 +21,9 @@ def write_csv(fname, conn, table):
writ = csv.writer(fname)
headers = [i[0] for i in cursor.description]
writ.writerow(headers)
writ.writerows(cursor)
for row in cursor:
writ.writerow([x if x else "NULL" for x in row])
#writ.writerows(cursor)
return headers

def call_vim(target, vim=None):
Expand Down Expand Up @@ -74,49 +75,68 @@ def decide_action(rows):
dels.append(ref)
return {'reference': refs, 'edit': edits, 'delete': dels}

def make_update_sql(table, headers):
def sql_param_char():
return "?"

def make_update_sql(table, headers, old_data, upd_data):
vclause = []
wclause = []
for col in headers:
old = []
upd = []
for col, odat, udat in zip(headers, old_data, upd_data):
odat = null_to_none(odat)
udat = null_to_none(udat)
vclause.append(", ")
vclause.append("{} = %s".format(col))
vclause.append("{} = {}".format(col, sql_param_char()))
wclause.append(" and ")
wclause.append("{} = %s".format(col))
if odat:
wclause.append("{} = {}".format(col, sql_param_char()))
old.append(odat)
else:
wclause.append("{} is null".format(col))
upd.append(udat)
vclause = "".join(vclause[1:])
wclause = "".join(wclause[1:])
return "update {} set {} where {}".format(table, vclause, wclause)
query = "update {} set {} where {}".format(table, vclause, wclause)
return query, upd + old

def null_to_none(item):
return None if item == "NULL" else item

def do_updates(table, headers, reference, edited, conn):
query = make_update_sql(table, headers)

data = (e + r for r, e in zip(reference, edited))

try:
cur = conn.cursor()
cur.executemany(query, data)
#FIXME: should happen further up?
for r, e in zip(reference, edited):
query, params = make_update_sql(table, headers, r, e)
cur.execute(query, params)
conn.commit()
print (cur.rowcount, "Rows updated")
except Exception as error:
raise RuntimeError("DB error:", error)
finally:
cur.close()

def make_delete_sql(table, headers):
def make_delete_sql(table, headers, data):
wclause = []
for col in headers:
out = []
for col, dat in zip(headers, data):
dat = null_to_none(dat)
wclause.append(" and ")
wclause.append("{} = %s".format(col))
if dat:
wclause.append("{} = {}".format(col, sql_param_char()))
out.append(dat)
else:
wclause.append("{} is null".format(col))
wclause = "".join(wclause[1:])
return "delete from {} where {}".format(table, wclause)
sql = "delete from {} where {}".format(table, wclause)
return sql, out

def do_deletes(table, headers, deletes, conn):
query = make_delete_sql(table, headers)

try:
cur = conn.cursor()
cur.executemany(query, deletes)
#FIXME: should happen further up?
for dl in deletes:
query, params = make_delete_sql(table, headers, dl)
cur.execute(query, params)
conn.commit()
print (cur.rowcount, "Rows deleted")
except Exception as error:
Expand Down

0 comments on commit 40de3c5

Please sign in to comment.