My company gets a few flat files each week that needs to be uploaded into our database. These are usually split off into two separate tables depending on the naming conventions of the file. The source of the files are consistent and the columns are validated before running the python script. Attached is what the code currently looks like
import glob
import pandas as pd
import numpy
import pyodbc as dbc
def uploadPerson(filename):
conn = dbc.connect('Driver={SQL Server Native Client 11.0};Server=SERVERNAME;Database=DATABASENAME;Trusted_Connection=yes;')
df = pd.read_excel(filename)
cursor = conn.cursor()
output = df.values.tolist()
cursor.executemany("INSERT INTO DATABASENAME.dbo.Person VALUES(?,?,?,?)", output)
conn.commit()
print('{0} imported - Rows: {1}, Columns: {2}'.format(filename,len(df),len(df.columns)))
cursor.close()
conn.close()
def uploadCustomer(filename):
conn = dbc.connect('Driver={SQL Server Native Client 11.0};Server=SERVERNAME;Database=DATABASENAME;Trusted_Connection=yes;')
df = pd.read_excel(filename)
cursor = conn.cursor()
output = df.values.tolist()
cursor.executemany("INSERT INTO DATABASENAME.dbo.Customer VALUES(?,?,?,?,?,?)", output)
conn.commit()
print('{0} imported - Rows: {1}, Columns: {2}'.format(filename,len(df),len(df.columns)))
cursor.close()
conn.close()
def main():
print('Starting Program')
for filename in glob.glob('*.xlsx'):
if 'Person' in filename:
uploadPerson(filename)
elif 'Customer' in filename:
uploadCustomer(filename)
else:
print('{0} cannot be imported, incorrect name'.format(filename))
print('Program Finished')
My questions are:
- Is it better to implicitly declare the connection/close to the database within each function or state it once in the main function and only perform commits in each function? Not sure how much of a performance hit this takes and was curious what is the best practice using pyodbc.
- If multiple queries are going to be called to different, is it best to initialize/close the cursor?
- Since the functions basically handle the same way aside from the SQL would it be better to statically define the sql with if/else and just have one upload function?
With the refactored code, would this be more pythonic and efficient with runtime?
import glob
import pandas as pd
import numpy
import pyodbc as dbc
def uploadPerson(filename,conn,cursor):
df = pd.read_excel(filename)
output = df.values.tolist()
cursor.executemany("INSERT INTO DATABASENAME.dbo.Person VALUES(?,?,?,?)", output)
conn.commit()
print('{0} imported - Rows: {1}, Columns: {2}'.format(filename,len(df),len(df.columns)))
def uploadCustomer(filename,conn,curosr):
df = pd.read_excel(filename)
output = df.values.tolist()
cursor.executemany("INSERT INTO DATABASENAME.dbo.Customer VALUES(?,?,?,?,?,?)", output)
conn.commit()
print('{0} imported - Rows: {1}, Columns: {2}'.format(filename,len(df),len(df.columns)))
def main():
print('Starting Program')
conn = dbc.connect('Driver={SQL Server Native Client 11.0};Server=SERVERNAME;Database=DATABASENAME;Trusted_Connection=yes;')
cursor = conn.cursor()
for filename in glob.glob('*.xlsx'):
if 'Person' in filename:
uploadPerson(filename, conn, cursor)
elif 'Customer' in filename:
uploadCustomer(filename, conn, cursor)
else:
print('{0} cannot be imported, incorrect name'.format(filename))
cursor.close()
conn.close()
print('Program Finished')
A bit newer to programming with pyodbc so best practices would be appreciated!