简体   繁体   中英

How to increment the value of a variable in a loop for insert sql statement using pyodbc

I'm attempting to pull employee timecard data from an API and subsequently insert it into a sql database. I want the code to look at the data, isolate the punches in and out for a specific date and then insert them into the sql database. The only catch is that the database requires a sequence number "SEQ_NO" to indicate which punch of the day it was to account for breaks, lunches etc. so I want it to loop increasing the sequence number by 1 without executing the header insert more than once for the same employee(eventually "kelly walton" and "080098" will be replaced with variables so that this can execute for every employee in the data set.

I've tried just about every variable incrementation method I've found on stack overflow and I cannot get it to work. for loops, while loops if, elif statements you name it and I can't get anything to work. This is just one version of the code. To clarify the issue is that no matter which type of loop I try to use it tries to duplicate some of the values either the header query or the punch data resulting in errors in the sql database.

today = ('2019-06-05')
with open('timepunches.json', 'r') as f:
    timepunches_dict = json.load(f)
for punch in timepunches_dict:
    punch_in = punch['PunchInDateTime']
    punch_out = punch['PunchOutDateTime']
    punch_in_sql = punch_in.replace('T', ' ')
    punch_out_sql = punch_out.replace('T', ' ')
    if today in punch_in_sql:
        #print(punch_in_sql, punch_out_sql)
        cnx = pyodbc.connect('driver={SQL Server};server=MY_server;database=my_db;uid=****;pwd=****')
        cursor = cnx.cursor()
        sequence_number = 1
            if sequence_number == 1:
                sql_insert_header_query = ''' INSERT INTO my_db.dbo.SY_TIMCRD_HDR
                    (STR_ID, USR_ID, TIMCRD_DAT, USR_NAM) VALUES ('M-MAC', '080098', '2019-06-05 00:00:00.000', 'Kelly Walton')'''
                sql_timecard_data = '''INSERT INTO my_db.dbo.SY_TIMCRD_LIN
                    (STR_ID, USR_ID, TIMCRD_DAT, SEQ_NO, CLCK_IN_TIM) VALUES ('M-MAC', '080098', [dbo].[fnDateOnly]('%s'), '%s', [dbo].[fnTimeOnly]('%s'))'''
                cursor.execute(sql_insert_header_query)
                cursor.execute(sql_timecard_data % (today, sequence_number, punch_in_sql))
                sequence_number+=1
            elif sequence_number == 2:
                sql_timecard_data = '''INSERT INTO my_db.dbo.SY_TIMCRD_LIN
                    (STR_ID, USR_ID, TIMCRD_DAT, SEQ_NO, CLCK_OUT_TIM) VALUES ('M-MAC', '080098', [dbo].[fnDateOnly]('%s'), '%s', [dbo].[fnTimeOnly]('%s'))'''
                cursor.execute(sql_insert_header_query)
                cursor.execute(sql_timecard_data % (today, sequence_number, punch_out_sql))
                sequence_number+=1            
        cnx.commit()
        cnx.close()

I thought this would increase 'sequence_number' to 2 and execute the next part. and I intended to add more statements once I got this part working.

Edit: This is the JSON data in 'timepunches.json' which may be helpful.

[{"JobCodeId": null, 
    "PunchInApprovalStatusId": 4, 
    "PunchInImageUrl": "", 
    "LocationName": "", 
    "PunchInNotes": "", 
    "PunchOutLongitude": null, 
    "PunchOutLatitude": null, 
    "Employee": 
        {"Username": "starlord", 
        "EmployeeId":"080097", 
        "FirstName": "Peter", 
        "LastName": "Quill", 
        "ProfileMiniImageUrl": "https://buddypunchapp.blob.core.windows.net/profileminipics/new_employee_face2.jpg", 
        "Email": "starlord@email.com", 
        "FullName": "Peter Quill", 
        "Id": 346968, 
        "IsActive": true}, 
    "PunchOutDateTime": "2019-06-10T10:00:00", 
    "BreakMinutes": 0, 
    "Hours": 2.0, 
    "PunchOutApprovalStatusName": "Changed By Manager", 
    "OverTimeHours": 0.0, 
    "DoubleTimeHours": 0.0, 
    "JobCodeName": "", 
    "PunchInIpAddress": "", 
    "PunchInApprovalStatusName": "Changed By Manager", 
    "PTOEarningCodeAbbr": "", 
    "PunchOutIpAddress": "", 
    "PunchOutImageUrl": "", 
    "PunchInLongitude": null, 
    "BreakApprovalStatusId": null, 
    "BreakApprovalStatusName": null, 
    "PTOHours": null, 
    "PunchOutApprovalStatusId": 4, 
    "PunchInDateTime": "2019-06-10T08:00:00", 
    "PunchOutNotes": "", 
    "PTOEarningCodeId": null, 
    "Id": 12971600, 
    "PunchInLatitude": null, 
    "LocationId": null, 
    "Duration": "02:00:00", 
    "RegularHours": 2.0}, 

    {"JobCodeId": null, 
    "PunchInApprovalStatusId": 4, 
    "PunchInImageUrl": "", 
    "LocationName": "", 
    "PunchInNotes": "", 
    "PunchOutLongitude": null, 
    "PunchOutLatitude": null, 
    "Employee": {
        "Username": "starlord", 
        "EmployeeId": "080097", 
        "FirstName": "Peter", 
        "LastName": "Quill", 
        "ProfileMiniImageUrl": "https://buddypunchapp.blob.core.windows.net/profileminipics/new_employee_face2.jpg", 
        "Email": "starlord@email.com", 
        "FullName": "Peter Quill", 
        "Id": 346968, 
        "IsActive": true}, 
    "PunchOutDateTime": "2019-06-10T12:00:00", 
    "BreakMinutes": 0, 
    "Hours": 1.75, 
    "PunchOutApprovalStatusName": "Changed By Manager", 
    "OverTimeHours": 0.0, 
    "DoubleTimeHours": 0.0, 
    "JobCodeName": "", 
    "PunchInIpAddress": "", 
    "PunchInApprovalStatusName": "Changed By Manager", 
    "PTOEarningCodeAbbr": "", 
    "PunchOutIpAddress": ", 
    "PunchOutImageUrl": "", 
    "PunchInLongitude": null, 
    "BreakApprovalStatusId": null, 
    "BreakApprovalStatusName": null, 
    "PTOHours": null, 
    "PunchOutApprovalStatusId": 4, 
    "PunchInDateTime": "2019-06-10T10:15:00", 
    "PunchOutNotes": "", 
    "PTOEarningCodeId": null, 
    "Id": 12971609, 
    "PunchInLatitude": null, 
    "LocationId": null, 
    "Duration": "01:45:00", 
    "RegularHours": 1.75}, 

    {"JobCodeId": null, 
    "PunchInApprovalStatusId": 4, 
    "PunchInImageUrl": "", 
    "LocationName": "", 
    "PunchInNotes": "", 
    "PunchOutLongitude": null, 
    "PunchOutLatitude": null, 
    "Employee": {
        "Username": "starlord", 
        "EmployeeId": "080097", 
        "FirstName": "Peter", 
        "LastName": "Quill", 
        "ProfileMiniImageUrl": "https://buddypunchapp.blob.core.windows.net/profileminipics/new_employee_face2.jpg", 
        "Email": "starlord@email.com", 
        "FullName": "Peter Quill", 
        "Id": 346968, 
        "IsActive": true}, 
    "PunchOutDateTime": "2019-06-10T15:00:00", 
    "BreakMinutes": 0, 
    "Hours": 2.0, 
    "PunchOutApprovalStatusName": "Changed By Manager", 
    "OverTimeHours": 0.0, 
    "DoubleTimeHours": 0.0, 
    "JobCodeName": "", 
    "PunchInIpAddress": "", 
    "PunchInApprovalStatusName": "Changed By Manager", 
    "PTOEarningCodeAbbr": "", 
    "PunchOutIpAddress": "", 
    "PunchOutImageUrl": "", 
    "PunchInLongitude": null, 
    "BreakApprovalStatusId": null, 
    "BreakApprovalStatusName": null, 
    "PTOHours": null, 
    "PunchOutApprovalStatusId": 4, 
    "PunchInDateTime": "2019-06-10T13:00:00", 
    "PunchOutNotes": "", 
    "PTOEarningCodeId": null, 
    "Id": 12971618, 
    "PunchInLatitude": null, 
    "LocationId": null, 
    "Duration": "02:00:00", 
    "RegularHours": 2.0}, 

    {"JobCodeId": null, 
    "PunchInApprovalStatusId": 4, 
    "PunchInImageUrl": "", 
    "LocationName": "", 
    "PunchInNotes": "", 
    "PunchOutLongitude": null, 
    "PunchOutLatitude": null, 
    "Employee": {
        "Username": "starlord", 
        "EmployeeId": "080097", 
        "FirstName": "Peter", 
        "LastName": "Quill", 
        "ProfileMiniImageUrl": "https://buddypunchapp.blob.core.windows.net/profileminipics/new_employee_face2.jpg", 
        "Email": "starlord@email.com", 
        "FullName": "Peter Quill", 
        "Id": 346968, 
        "IsActive": true}, 
    "PunchOutDateTime": "2019-06-10T17:00:00", 
    "BreakMinutes": 0, 
    "Hours": 1.75, 
    "PunchOutApprovalStatusName": "Changed By Manager", 
    "OverTimeHours": 0.0, 
    "DoubleTimeHours": 0.0, 
    "JobCodeName": "", 
    "PunchInIpAddress": "", 
    "PunchInApprovalStatusName": "Changed By Manager", 
    "PTOEarningCodeAbbr": "", 
    "PunchOutIpAddress": "", 
    "PunchOutImageUrl": "", 
    "PunchInLongitude": null, 
    "BreakApprovalStatusId": null, 
    "BreakApprovalStatusName": null, 
    "PTOHours": null, 
    "PunchOutApprovalStatusId": 4, 
    "PunchInDateTime": "2019-06-10T15:15:00", 
    "PunchOutNotes": "", 
    "PTOEarningCodeId": null, 
    "Id": 12971630, 
    "PunchInLatitude": null, 
    "LocationId": null, 
    "Duration": "01:45:00", 
    "RegularHours": 1.75}]

Consider the following adjustment to your process using enumerate() during loop for a sequence number and importantly employing parameterization and not string interpolation.

# VARIABLES
today = '2019-06-05'

# OPEN CONNECTION AND CURSOR
cnx = pyodbc.connect('driver={SQL Server};server=MY_server;database=my_db;uid=****;pwd=****')
cursor = cnx.cursor()

# PREPARED STATEMENTS
sql_insert_header_query = '''INSERT INTO my_db.dbo.SY_TIMCRD_HDR (STR_ID, USR_ID, TIMCRD_DAT, USR_NAM) 
                             VALUES ('M-MAC', ?, ?, ?)
                          '''

sql_timecard_data = '''INSERT INTO my_db.dbo.SY_TIMCRD_LIN (STR_ID, USR_ID, TIMCRD_DAT, SEQ_NO, CLCK_IN_TIM) 
                       VALUES ('M-MAC', ?, [dbo].[fnDateOnly](?), ?, [dbo].[fnTimeOnly](?))
                    '''

with open('timepunches.json', 'r') as f:
    timepunches_dict = json.load(f)

for i, punch in enumerate(timepunches_dict):
    punch_in = punch['PunchInDateTime']
    punch_out = punch['PunchOutDateTime']
    punch_in_sql = punch_in.replace('T', ' ')
    punch_out_sql = punch_out.replace('T', ' ')

    emp_id = punch['Employee']['EmployeeId']
    emp_name = punch['Employee']['FullName']

    if today in punch_in_sql:
        #print(punch_in_sql, punch_out_sql)

        if i == 0:
            # ONLY RUN FOR FIRST ITERATION 
            cursor.execute(sql_insert_header_query, (emp_id, today, emp_name))
            cnx.commit()     

        # RUN FOR ALL ITERATIONS
        cursor.execute(sql_timecard_data, (emp_id, today, i+1, punch_in_sql))        
        cnx.commit()

cursor.close()
cnx.close() 

Rextester Demo (minus database objects)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM