Compare commits

...
Sign in to create a new pull request.

7 commits

203
sql.py
View file

@ -1,30 +1,48 @@
#!/usr/bin/env python2.4 #!/usr/bin/python3
import cx_Oracle
import sys
import os import os
import sys
import sqlalchemy
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 = " "):
def pad(s, l, padchar=" "):
padding = padchar * l padding = padchar * l
return (s + padding)[:l] return (s + padding)[:l]
rowbuffer = None rowbuffer = None
def print_row():
def execute_cmdline_query(v):
global rowbuffer 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():
global rowbuffer, cur, db
if not cur or not cur.description: if not cur or not cur.description:
return False return False
try: try:
@ -41,8 +59,8 @@ def print_row():
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
@ -68,31 +86,60 @@ def print_row():
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
db = cx_Oracle.connect(connstr)
cur = db.cursor()
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 = ""
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()
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 = raw_input('# ') v = input('# ')
except EOFError: except EOFError:
do_quit = True do_quit = True
@ -107,32 +154,85 @@ while True:
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(' ')
conds = ["tablespace_name != '%s'" % (x,) for x in opts['hide_tablespaces'].split(';')]
if opts['hide_null_tablespace'][0:1] in ('1', 'Y', 'y', 'T', 't'):
conds += ['tablespace_name is not null']
conds = ' and '.join(conds)
if conds:
conds = ' where ' + conds
cur.execute("select table_name, tablespace_name from all_tables %s" % (conds,))
print_row()
elif vl[:5] == 'exec ':
cmd = v[5:]
try: try:
exec cmd configsrc = inifile.inifile(vs[1])
connstrsrc = configsrc['settings']['db']
esrc = sqlalchemy.create_engine(connstrsrc)
poolsrc = e.connect()
dbsrc = pool.connection
cursrc = db.cursor()
c2 = db.cursor()
#c2.execute("select * from %s where 1 is null" % (vs[2],))
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: except:
traceback.print_exc() 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 ': elif vl[:5] == 'cols ':
rowbuffer = None rowbuffer = None
vs = v.split(' ') vs = v.split(' ')
c2 = db.cursor() c2 = db.cursor()
try: try:
c2.execute("select * from %s where 1 is null" % (vs[1],)) c2.execute("select * from %s where 1 is null" % (vs[1],))
for coldata in c2.description: for coldata in c2.description:
print "%s%s" % (softpad(coldata[0], 40), coldata[1]) typedata = coldata[1]
except cx_Oracle.DatabaseError, e: try:
sys.stdout.write(str(e)) 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 ': elif vl[:4] == 'set ':
vs = v[4:] vs = v[4:]
vi = vs.find('=') vi = vs.find('=')
@ -142,31 +242,20 @@ while True:
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
set <key>=<val> sets internal options, like "set page=40" to page at 40 rows
help displays this help 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 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 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 ""