Ich arbeite an einem Python-Skript, das Abfragen für eine Oracle-Datenbank ausführt und speichert die Ergebnisse in CSV. Der größere Plan besteht darin, reguläre Extrakte mit einer separaten Anwendung zu verwenden, um Unterschiede in den Dateien durch Hashing zu überprüfen.Python cx_Oracle und CSV-Extrakte mit unterschiedlichen Ausführungen unterschiedlich gespeichert
Das Problem, das ich habe, ist, dass mein Skript bisher einige Felder in den Extrakten in verschiedenen Formaten gespeichert hat. Beispielsweise Speichern eines Felds als Ganzzahl in einem Extrakt und als Float im nächsten und Speichern eines Datums am 2000/01/01 in einem und 2000-01-01 in einem anderen.
Diese Änderungen geben meinem Unterschied Prüfskript eine Passform. Was kann ich tun, um sicherzustellen, dass jeder Extrakt auf die gleiche Weise gespeichert wird, während das Skript generisch genug bleibt, um beliebige Abfragen auszuführen?
import sys
import traceback
import cx_Oracle
from Creds import creds
import csv
import argparse
import datetime
try:
conn = cx_Oracle.connect(
'{username}/{password}@{address}/{dbname}'.format(**creds)
)
except cx_Oracle.Error as e:
print('Unable to connect to database.')
print()
print(''.join(traceback.format_exception(*sys.exc_info())), file=sys.stderr)
sys.exit(1)
def run_extract(query, out):
"""
Run the given query and save results to given out path.
:param query: Query to be executed.
:param out: Path to store results in csv.
"""
cur = conn.cursor()
try:
cur.execute(query)
except cx_Oracle.DatabaseError as e:
print('Unable to run given query.')
print()
print(query)
print()
print(''.join(traceback.format_exception(*sys.exc_info())), file=sys.stderr)
sys.exit(1)
with open(out, 'w', newline='') as out_file:
wrt = csv.writer(out_file)
header = []
for column in cur.description:
header.append(column[0])
wrt.writerow(header)
for row in cur:
wrt.writerow(row)
cur.close()
def read_sql(file_path):
"""
Read the SQL from a given filepath and return as a string.
:param file_path: File path location of the file to read.
"""
try:
with open(file_path, 'r') as file:
return file.read()
except FileNotFoundError as e:
print('File not found a given path.')
print()
print(file_path)
print()
print(''.join(traceback.format_exception(*sys.exc_info())), file=sys.stderr)
sys.exit(1)
def generate_timestamp_path(path):
"""
Add a timestamp to the beginning of the given path.
:param path: File path for the timestamp to be added to.
"""
if '/' in args.out_file:
sep = '/'
elif '\\' in args.out_file:
sep = '\\'
else:
sep = ''
path = args.out_file.split(sep)
stamp = datetime.datetime.now().strftime('%Y%m%dT%H%M%S ')
path[-1] = stamp + path[-1]
return sep.join(path)
if __name__ == '__main__':
parser = argparse.ArgumentParser()
in_group = parser.add_mutually_exclusive_group()
in_group.add_argument('-q', '--query', help='String of the query to run.')
in_group.add_argument('-f', '--in_file', help='File of the query to run.')
parser.add_argument('-o', '--out_file', help='Path to file to store.')
parser.add_argument('-t', '--timestamp',
help='Store the file with a preceding timestamp.',
action='store_true')
args = parser.parse_args()
if not args.out_file:
print('Please provide a path to put the query results with -o.')
sys.exit(1)
if args.timestamp:
path = generate_timestamp_path(args.out_file)
else:
path = args.out_file
if args.query:
query = args.query
elif args.in_file:
query = read_sql(args.in_file)
else:
print('Please provide either a query string with -q',
'or a SQL file with -f.')
sys.exit(1)
run_extract(query, path)
In meiner Verarbeitung für diese Zeit lief das Skript buchstäblich die gleiche Abfrage 8 Sekunden voneinander getrennt. Ich werde die Ausgabetyphandler nachschlagen. :-) – user2004245
Hmm, neugierig! Ich würde gerne einen Testfall haben, der dieses Verhalten demonstriert. Wenn Sie einen haben, lassen Sie es mich bitte wissen! Vielen Dank. –