如何使用 pyodbc 在循环中增加变量的值 for insert sql 语句
How to increment the value of a variable in a loop for insert sql statement using pyodbc
我正在尝试从 API 中提取员工考勤卡数据,然后将其插入到 sql 数据库中。我希望代码查看数据,隔离特定日期的输入和输出,然后将它们插入 sql 数据库。唯一的问题是数据库需要一个序列号 "SEQ_NO" 来指示它是一天中的哪个打卡时间来解决休息、午餐等问题,所以我希望它在不执行 [= 的情况下循环将序列号增加 1 26=] 为同一员工插入多次(最终 "kelly walton" 和“080098” 将被替换为变量,以便可以对数据集中的每个员工执行。
我已经尝试了几乎所有在堆栈溢出时发现的变量递增方法,但我无法让它工作。 for 循环、while 循环 if、elif 语句你都可以命名,但我什么都做不了。这只是代码的一个版本。为了澄清这个问题,无论我尝试使用哪种类型的循环,它都会尝试复制 header 查询或打孔数据中的某些值,从而导致 sql 数据库中出现错误。
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()
我认为这会将 'sequence_number' 增加到 2 并执行下一部分。我打算在这部分工作后添加更多语句。
编辑:这是 'timepunches.json' 中的 JSON 数据,可能会有帮助。
[{"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}]
考虑在序列号循环期间使用 enumerate()
对您的过程进行以下调整,重要的是使用 parameterization 而不是字符串插值。
# 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 (减去数据库对象)
我正在尝试从 API 中提取员工考勤卡数据,然后将其插入到 sql 数据库中。我希望代码查看数据,隔离特定日期的输入和输出,然后将它们插入 sql 数据库。唯一的问题是数据库需要一个序列号 "SEQ_NO" 来指示它是一天中的哪个打卡时间来解决休息、午餐等问题,所以我希望它在不执行 [= 的情况下循环将序列号增加 1 26=] 为同一员工插入多次(最终 "kelly walton" 和“080098” 将被替换为变量,以便可以对数据集中的每个员工执行。
我已经尝试了几乎所有在堆栈溢出时发现的变量递增方法,但我无法让它工作。 for 循环、while 循环 if、elif 语句你都可以命名,但我什么都做不了。这只是代码的一个版本。为了澄清这个问题,无论我尝试使用哪种类型的循环,它都会尝试复制 header 查询或打孔数据中的某些值,从而导致 sql 数据库中出现错误。
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()
我认为这会将 'sequence_number' 增加到 2 并执行下一部分。我打算在这部分工作后添加更多语句。
编辑:这是 'timepunches.json' 中的 JSON 数据,可能会有帮助。
[{"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}]
考虑在序列号循环期间使用 enumerate()
对您的过程进行以下调整,重要的是使用 parameterization 而不是字符串插值。
# 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 (减去数据库对象)