Compare commits

...

6 commits

358
sql.py
View file

@ -7,97 +7,123 @@ import readline
import traceback import traceback
def softpad(s, l, padchar=" "):
padding = padchar * l
if len(s) >= l:
return s + padchar
return (s + padding)[:l]
def softpad(s, l, padchar = " "): def pad(s, l, padchar=" "):
padding = padchar * l padding = padchar * l
if len(s) >= l: return (s + padding)[:l]
return s + padchar
return (s + padding)[:l]
def pad(s, l, padchar = " "):
padding = padchar * l
return (s + padding)[:l]
rowbuffer = None rowbuffer = None
def execute_cmdline_query(v):
global rowbuffer
rowbuffer = None
try:
v = v.rstrip(';')
cur.execute(v)
print_row()
except:
try:
c2 = db.cursor()
c2.execute(
"SELECT 1 FROM INFORMATION_SCHEMA.TABLES WHERE 1 IS NULL")
except:
print("Database connection lost!")
sys.exit(1)
traceback.print_exc()
sys.stdout.write('\n')
def print_row(): def print_row():
global rowbuffer, cur, db global rowbuffer, cur, db
if not cur or not cur.description: if not cur or not cur.description:
return False return False
try: try:
page = int(opts['page']) page = int(opts['page'])
colhdrs = [x[0] for x in cur.description] colhdrs = [x[0] for x in cur.description]
allcols = [] allcols = []
lens = [] lens = []
for i in range(len(colhdrs)): for i in range(len(colhdrs)):
l = min(len(colhdrs[i]), 10) l = min(len(colhdrs[i]), 10)
lens.append(l) lens.append(l)
if rowbuffer: if rowbuffer:
rowbuffer = [repr(x) for x in rowbuffer] rowbuffer = [repr(x) for x in rowbuffer]
allcols = [rowbuffer] allcols = [rowbuffer]
for i in range(len(rowbuffer)): for i in range(len(rowbuffer)):
l = len(rowbuffer[i]) l = len(rowbuffer[i])
if i > len(lens): if i > len(lens):
print(lens) print(lens)
print(rowbuffer) print(rowbuffer)
if l > lens[i]: if l > lens[i]:
lens[i] = l lens[i] = l
rowbuffer = None rowbuffer = None
while len(allcols) < page: while len(allcols) < page:
cols = cur.fetchone() cols = cur.fetchone()
if not cols: if not cols:
break break
cols = [repr(x) for x in cols] cols = [repr(x) for x in cols]
allcols.append(cols) allcols.append(cols)
for i in range(len(cols)): for i in range(len(cols)):
l = len(cols[i]) l = len(cols[i])
if l > lens[i]: if l > lens[i]:
lens[i] = l lens[i] = l
if not allcols: if not allcols:
return False return False
for i in range(len(colhdrs)): for i in range(len(colhdrs)):
colhdrs[i] = pad(colhdrs[i], lens[i]) colhdrs[i] = pad(colhdrs[i], lens[i])
for i in range(len(allcols)): for i in range(len(allcols)):
cols = allcols[i] cols = allcols[i]
for j in range(len(cols)): for j in range(len(cols)):
cols[j] = pad(cols[j], lens[j]) cols[j] = pad(cols[j], lens[j])
colhdrrow = ' | '.join(colhdrs) colhdrrow = ' | '.join(colhdrs)
seprow = '-' * len(colhdrrow) seprow = '-' * len(colhdrrow)
print(colhdrrow) print(colhdrrow)
print(seprow) print(seprow)
for cols in allcols: for cols in allcols:
colsrow = ' | '.join(cols) colsrow = ' | '.join(cols)
print(colsrow) print(colsrow)
rowbuffer = cur.fetchone() rowbuffer = cur.fetchone()
if rowbuffer: if rowbuffer:
print(" ( more ) ") print(" ( more ) ")
return True return True
except: except:
traceback.print_exc() traceback.print_exc()
return False return False
opts = { opts = {
'page': '20', 'page': '20',
'hide_null_tablespace': '1', 'hide_null_tablespace': '1',
'hide_tablespaces': 'SYSTEM;SYSAUX;SDE;SPATIAL_DATA' 'hide_tablespaces': 'SYSTEM;SYSAUX;SDE;SPATIAL_DATA'
} }
connstr = "" connstr = ""
if len(sys.argv) < 2: if os.path.exists('settings.ini'):
if os.path.exists('settings.ini'): try:
try: from cecil.core import inifile
from cecil.core import inifile config = inifile.inifile('settings.ini')
config = inifile.inifile('settings.ini') connstr = config['settings']['db']
connstr = config['settings']['db'] except None:
except: pass
pass cmdline_query = None
if not connstr:
if not connstr: if len(sys.argv) < 2:
connstr = input('Connect string: ') if not connstr:
else: connstr = input('Connect string: ')
connstr = sys.argv[1] else:
connstr = sys.argv[-1]
elif len(sys.argv) > 1:
cmdline_query = sys.argv[-1]
e = sqlalchemy.create_engine(connstr) e = sqlalchemy.create_engine(connstr)
pool = e.connect() pool = e.connect()
@ -105,69 +131,131 @@ db = pool.connection
cur = db.cursor() cur = db.cursor()
c2 = db.cursor() c2 = db.cursor()
if cmdline_query != None:
execute_cmdline_query(cmdline_query)
db.commit()
sys.exit(0)
do_quit = False do_quit = False
while True: while True:
try: try:
v = input('# ') v = input('# ')
except EOFError: except EOFError:
do_quit = True do_quit = True
if do_quit: if do_quit:
break break
v = v.strip() v = v.strip()
vl = v.lower() vl = v.lower()
if vl == 'quit' or vl == 'exit': if vl == 'quit' or vl == 'exit':
break break
elif vl == 'commit': elif vl == 'commit':
db.commit() db.commit()
elif vl == 'rollback': elif vl == 'rollback':
db.rollback() db.rollback()
elif vl == 'tables': elif vl[:4] == 'copy' or vl[:5] == 'copyi':
rowbuffer = None vs = v.split(' ')
cur.execute("SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES") try:
print_row() configsrc = inifile.inifile(vs[1])
elif vl[:5] == 'cols ': connstrsrc = configsrc['settings']['db']
rowbuffer = None esrc = sqlalchemy.create_engine(connstrsrc)
vs = v.split(' ') poolsrc = e.connect()
c2 = db.cursor() dbsrc = pool.connection
try: cursrc = db.cursor()
c2.execute("select * from %s where 1 is null" % (vs[1],))
for coldata in c2.description: c2 = db.cursor()
print("%s%s" % (softpad(coldata[0], 40), coldata[1])) #c2.execute("select * from %s where 1 is null" % (vs[2],))
except: cursrc.execute("select * from %s" % (vs[2],))
colnames = []
dstart = 1
if vs[0] == "copyi":
dstart = 0
for coldata in cursrc.description[dstart:]:
colnames.append(coldata[0])
rowload = 0
rowerror = 0
for r in cursrc:
try:
colnamesql = ", ".join(colnames)
colmarks = ", ".join("%s" for cn in colnames)
srcq = "insert into %s (%s) values (%s)" % (vs[2], colnamesql, colmarks)
print(srcq)
print(r[0])
print(r[1])
print(r[2])
print(len(r))
c2.execute(srcq, tuple(r[dstart:]))
except:
traceback.print_exc()
rowerror += 1
print(f"Rows loaded {rowload}, errors {rowerror}")
except:
traceback.print_exc()
elif vl == 'tables':
rowbuffer = None
cur.execute("SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES")
print_row()
elif vl[:7] == 'tables ':
v2 = v[7:]
rowbuffer = None
cur.execute("SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME LIKE %s" % (v2,))
print_row()
elif vl[:5] == 'cols ':
rowbuffer = None
vs = v.split(' ')
c2 = db.cursor()
try:
c2.execute("select * from %s where 1 is null" % (vs[1],))
for coldata in c2.description:
typedata = coldata[1]
try:
import pytds.tds_base
tdlist = []
for x in dir(pytds.tds_base):
if getattr(pytds.tds_base, x) == typedata:
tdlist.append(x)
if tdlist:
tdlist2 = [x.replace("NTYPE", "").replace(
"TYPE", "") for x in tdlist if "TYPE" in x]
if tdlist2:
tdlist = tdlist2
if tdlist:
tdlist.sort()
tdlist.sort(key=len)
typedata = " ".join(tdlist)
except:
pass
print("%s%s" % (softpad(coldata[0], 40), typedata))
except:
traceback.print_exc() traceback.print_exc()
sys.stdout.write('\n') sys.stdout.write('\n')
elif vl[:4] == 'set ': elif vl[:4] == 'set ':
vs = v[4:] vs = v[4:]
vi = vs.find('=') vi = vs.find('=')
vn = vs[:vi] vn = vs[:vi]
vv = vs[vi+1:] vv = vs[vi+1:]
opts[vn] = vv opts[vn] = vv
elif vl == '': elif vl == '':
print_row() print_row()
elif vl == 'help': elif vl == 'help':
print(""" print("""
commands: commands:
tables lists tables tables lists tables
cols <table> lists columns of table cols <table> lists columns of table
commit commits any pending updates or inserts commit commits any pending updates or inserts
rollback aborts and pending updates or inserts rollback aborts and pending updates or inserts
help displays this help set <key>=<val> sets internal options, like "set page=40" to page at 40 rows
quit exits sql.py help displays this help
copy <path> <tbl> reads the config from <path> connects to that database and copies the contents of <tbl>
quit exits sql.py
<empty line> next page if there are (MORE) pages, just hit "ENTER"
<anything else> executes SQL query on the server
""") """)
else: else:
rowbuffer = None execute_cmdline_query(v)
try:
v = v.rstrip(';')
cur.execute(v)
print_row()
except:
try:
c2 = db.cursor()
c2.execute("SELECT 1 FROM INFORMATION_SCHEMA.TABLES WHERE 1 IS NULL")
except:
print("Database connection lost!")
sys.exit(1)
sys.stdout.write(str(sys.exc_info))