Compare commits
6 commits
7423063b69
...
11d1609d4a
Author | SHA1 | Date | |
---|---|---|---|
11d1609d4a | |||
c8217ae176 | |||
47292a9b1b | |||
9b2ecd4762 | |||
de474553df | |||
259d6bdad2 |
1 changed files with 223 additions and 135 deletions
358
sql.py
358
sql.py
|
@ -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))
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue