2. Whoami
■ Started as a database kernel developer with C and C++
■ ORACLE DBA for ~ 14 years: + SQL, PL/SQL and Perl
■ Persistence Engineer for the last 4: + Python, R and Scala
■ OCM, ORACLE Ace Associate
■ Blog: http://intermediatesql.com
■ Twitter: @maxymkh
3. Agenda
■ Talk about why Python is awesome
■ Design ORACLE multi db “ping” in Python
■ (hopefully) Demo it
4. The job of an engineer is
to make complex things simple
6. Do I have a good datafilebackup ?
SELECT …
FROM v$backup_datafile
v$backup_datafile
Backup files actually exist
and can be validated
Backup size is plausible
On the end storage
Network transfer as well
No critical errors in logs
Etc
16. Python enforces good coding practices
for p in db1_params:
if p in db2_params:
if db1_params[p] == db2_params[p]:
same_parameters.append(p)
else:
diff_parameters.append(p)
else:
only_in_1.append(p)
23. If you know any scripting language
you (almost) know Python
24. Python is similar to other languages
def is_accessible(db_name):
""" Check if database is accessible """
ret = False
db_status = ping_db(db_name)
if "ACTIVE" == db_status:
ret = True
return ret
25. But: Spaces are first class citizens
def print_databases():
""" Print all databases from /etc/oratab """
with open("/etc/oratab") as file:
for line in file:
if line:
print line.strip().split(':')[0]
26. But: Spaces are first class citizens
def print_databases():
""" Print all databases from /etc/oratab ""“
with open("/etc/oratab") as file:
for line in file:
if line:
print line.strip().split(':')[0]
File "./a.py", line 7
print line.strip().split(':')[0]
^
IndentationError:
expected an indented block
27. Compare to Perl
sub print_databases() {
open(my $f, "<", "/etc/oratab")
or die ("Unable to open: $!");
while(my $line = <$f>) {
if ($line =~ /S+/) {
my @aItems = split(':', $line);
print $aItems[0] . "n";
}
}
close($f);
}
28. Compare to Perl
sub print_databases(){open(my $f, "<", "/etc/oratab") or
die ("Unable to open: $!"); while(my $line = <$f>) {
if ($line =~ /S+/) {my @aItems = split(':', $line);
print $aItems[0] . "n";}} close($f);}
30. Fun with functions
def outer_function(parameter_function):
""" This function accepts function as a parameter """
def inner_function(inner_parameter):
""" This is a nested function """
return inner_parameter
# This returns a function from a function
return inner_function(parameter_function)
# This "calls" function return value as a function
print outer_function(external_function)()
31. Fun with functions: Decorators
def do_stuff():
result = heavy_processing()
def do_stuff():
start = time()
result = heavy_processing()
end = time()
print "Elapsed: %f" % (end-start)
def do_stuff2():
…
def do_stuff3076():
32. Fun with functions: Decorators
def timeit(func):
""" Generic time profiling function """
def time_exec(*args, **kwargs):
start_time = time()
ret = func(*args, **kwargs)
end = time()
print "Elapsed: %f" % (end-start)
return ret
return time_exec
33. Fun with functions: Decorators
do_stuff = timeit(do_stuff)
@timeit
def do_stuff():
…
@timeit
def do_stuff2():
…
@timeit
def do_stuff3076():
…
34. Learn to think Pythonian. It helps!
def print_databases():
file = open('/etc/oratab', 'r')
while True:
line = file.readline()
if len(line) == 0 and not line.endswith('n'):
break
print line.strip().split(':')[0]
file.close()
def print_databases():
with open('/etc/oratab') as file:
for line in file:
print line.strip().split(':')[0]
40. Database “multi ping”
import dbping
def multi_dbping(db_list, ping_routine):
""" Ping all databases in a list """
for db in db_list:
ping_routine(db)
> dbping_list.py c15lv1 c15lv2 c15lv3
PING [c15lv1]: OK
PING [c15lv2]: UNAVAILABLE
PING [c15lv3]: OK
41. Parallel database “multi ping”
import multiprocessing
def parallel_ping(db_list, target=dbping.print_dbping):
""" Ping db_list databases in parallel """
jobs = []
for d in db_list:
p = multiprocessing.Process(
target=target, args=(d,)
)
jobs.append(p)
p.start()
for p in jobs:
p.join()
42. Parallel database “multi ping”
> dbping_parallel.py c15lv1 c15lv2 c15lv3 c15lv4
PING [c15lv1]: OK
PING [c15lv3]: OK
PING [c15lv4]: OK
PING [c15lv2]: UNAVAILABLE
43. Decorator: Execution Timing
def timeit(func):
""" Generic time profiling function """
def time_exec(*args, **kwargs):
start_time = time()
ret = func(*args, **kwargs)
ela = time() - start_time
print “tElapsed: %.3f seconds" % ela
return ret
return time_exec
45. How to start with Python
■ Lots of free resources on the web
▪ Tutorials
▪ Documentation
▪ Stackoverflow.com
▪ “Play” environments
▪ Even books
■ Python self documentation:
▪ dir()
▪ help()