Compare commits

..

No commits in common. "main" and "cx_oracle" have entirely different histories.

401
sql.py
View file

@ -1,261 +1,172 @@
#!/usr/bin/python3 #!/usr/bin/env python2.4
import cx_Oracle
import os
import sys import sys
import sqlalchemy import os
import readline
import traceback import traceback
try:
import readline
except ImportError:
pass
if len(sys.argv) < 2:
connstr = raw_input('Connect string: ')
else:
connstr = sys.argv[1]
def softpad(s, l, padchar=" "): def softpad(s, l, padchar = " "):
padding = padchar * l padding = padchar * l
if len(s) >= l: if len(s) >= l:
return s + padchar return s + padchar
return (s + padding)[:l] return (s + padding)[:l]
def pad(s, l, padchar = " "):
padding = padchar * l
def pad(s, l, padchar=" "): return (s + padding)[:l]
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
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)
seprow = '-' * len(colhdrrow)
print colhdrrow
print seprow
for cols in allcols:
colsrow = ' | '.join(cols)
print colsrow
rowbuffer = cur.fetchone()
if rowbuffer:
print " ( more ) "
return True
except:
traceback.print_exc()
return False
colhdrrow = ' | '.join(colhdrs) db = cx_Oracle.connect(connstr)
seprow = '-' * len(colhdrrow)
print(colhdrrow)
print(seprow)
for cols in allcols:
colsrow = ' | '.join(cols)
print(colsrow)
rowbuffer = cur.fetchone()
if rowbuffer:
print(" ( more ) ")
return True
except:
traceback.print_exc()
return False
opts = {
'page': '20',
'hide_null_tablespace': '1',
'hide_tablespaces': 'SYSTEM;SYSAUX;SDE;SPATIAL_DATA'
}
connstr = ""
if os.path.exists('settings.ini'):
try:
from cecil.core import inifile
config = inifile.inifile('settings.ini')
connstr = config['settings']['db']
except None:
pass
cmdline_query = None
if not connstr:
if len(sys.argv) < 2:
if not connstr:
connstr = input('Connect string: ')
else:
connstr = sys.argv[-1]
elif len(sys.argv) > 1:
cmdline_query = sys.argv[-1]
e = sqlalchemy.create_engine(connstr)
pool = e.connect()
db = pool.connection
cur = db.cursor() cur = db.cursor()
c2 = db.cursor() opts = {
'page': '20',
if cmdline_query != None: 'hide_null_tablespace': '1',
execute_cmdline_query(cmdline_query) 'hide_tablespaces': 'SYSTEM;SYSAUX;SDE;SPATIAL_DATA'
db.commit() }
sys.exit(0)
do_quit = False do_quit = False
while True: while True:
try: try:
v = input('# ') v = raw_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[:4] == 'copy' or vl[:5] == 'copyi': elif vl == 'tables':
vs = v.split(' ') rowbuffer = None
try: conds = ["tablespace_name != '%s'" % (x,) for x in opts['hide_tablespaces'].split(';')]
configsrc = inifile.inifile(vs[1]) if opts['hide_null_tablespace'][0:1] in ('1', 'Y', 'y', 'T', 't'):
connstrsrc = configsrc['settings']['db'] conds += ['tablespace_name is not null']
esrc = sqlalchemy.create_engine(connstrsrc) conds = ' and '.join(conds)
poolsrc = e.connect() if conds:
dbsrc = pool.connection conds = ' where ' + conds
cursrc = db.cursor() cur.execute("select table_name, tablespace_name from all_tables %s" % (conds,))
print_row()
c2 = db.cursor() elif vl[:5] == 'exec ':
#c2.execute("select * from %s where 1 is null" % (vs[2],)) cmd = v[5:]
cursrc.execute("select * from %s" % (vs[2],)) try:
colnames = [] exec cmd
dstart = 1 except:
if vs[0] == "copyi": traceback.print_exc()
dstart = 0 elif vl[:5] == 'cols ':
for coldata in cursrc.description[dstart:]: rowbuffer = None
colnames.append(coldata[0]) vs = v.split(' ')
rowload = 0 c2 = db.cursor()
rowerror = 0 try:
for r in cursrc: c2.execute("select * from %s where 1 is null" % (vs[1],))
try: for coldata in c2.description:
colnamesql = ", ".join(colnames) print "%s%s" % (softpad(coldata[0], 40), coldata[1])
colmarks = ", ".join("%s" for cn in colnames) except cx_Oracle.DatabaseError, e:
srcq = "insert into %s (%s) values (%s)" % (vs[2], colnamesql, colmarks) sys.stdout.write(str(e))
print(srcq) elif vl[:4] == 'set ':
print(r[0]) vs = v[4:]
print(r[1]) vi = vs.find('=')
print(r[2]) vn = vs[:vi]
print(len(r)) vv = vs[vi+1:]
c2.execute(srcq, tuple(r[dstart:])) opts[vn] = vv
except: elif vl == '':
traceback.print_exc() print_row()
rowerror += 1 elif vl == 'help':
print(f"Rows loaded {rowload}, errors {rowerror}") print """
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()
sys.stdout.write('\n')
elif vl[:4] == 'set ':
vs = v[4:]
vi = vs.find('=')
vn = vs[:vi]
vv = vs[vi+1:]
opts[vn] = vv
elif vl == '':
print_row()
elif vl == 'help':
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
set <key>=<val> sets internal options, like "set page=40" to page at 40 rows help displays this help
help displays this help quit exits sql.py
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:
execute_cmdline_query(v)
else:
rowbuffer = None
try:
v = v.rstrip(';')
cur.execute(v)
print_row()
except cx_Oracle.DatabaseError, e:
try:
cur.execute("SELECT 1 FROM DUAL")
except cx_Oracle.DatabaseError:
print "Database connection lost!"
sys.exit(1)
sys.stdout.write(str(e))
print ""