Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/359.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python脚本向表中写入两次_Python_Sql_Sql Server_Xml - Fatal编程技术网

Python脚本向表中写入两次

Python脚本向表中写入两次,python,sql,sql-server,xml,Python,Sql,Sql Server,Xml,我正在尝试将此场景自动化。我有2个.sql文件(add1.sql和add2.sql),每个文件有1个插入脚本 我的目标是通过执行add1.sql中的行将一条记录写入table1,并通过执行add2.sql中的行将一条记录写入cm.cl,等待大约5分钟,以便后端服务运行。此服务从DB1写入DB2。然后连接到DB2,查看DB1中的记录是否与写入DB2的记录匹配。根据结果,将发送电子邮件 下面是我的代码。除了向DB1写入两次之外,其他一切都正常工作。因此,基本上插入了4条记录,而不是2条。知道它为什么

我正在尝试将此场景自动化。我有2个.sql文件(add1.sql和add2.sql),每个文件有1个插入脚本

我的目标是通过执行add1.sql中的行将一条记录写入table1,并通过执行add2.sql中的行将一条记录写入cm.cl,等待大约5分钟,以便后端服务运行。此服务从DB1写入DB2。然后连接到DB2,查看DB1中的记录是否与写入DB2的记录匹配。根据结果,将发送电子邮件

下面是我的代码。除了向DB1写入两次之外,其他一切都正常工作。因此,基本上插入了4条记录,而不是2条。知道它为什么写4张唱片吗

import pypyodbc as pyodbc
import smtplib
sender = 'abc@abc.com'
receivers = ['abc@abc.com','xyz@abc.com']
import unittest
import time

class TestDB1(unittest.TestCase):


    def testing_master(self):

           Master_Conn = 'Driver=
 {SQLServer};Server=server\servername;Database=database;UID=userid;PWD=password'
           Master_db = pyodbc.connect(Master_Conn)
           Master_Cursor = Master_db.cursor()
           try:
               #Open, read and execute add_shell.sql
               file = open('C:\\aaa\\add1.sql', 'r')
               line = file.read()
               lines = line.replace('\n', ' ')
               file1 = open('C:\\aaa\\add2.sql', 'r')
               line1=file1.read()
               lines1=line1.replace('\n', ' ')
               Master_Cursor.execute(lines)
               time.sleep(1)
               Master_Cursor.execute(lines1)
               Master_db.commit()
               file.close()
               file1.close()

               #Get python object for latest record inserted in DB1
               Master_CID=Master_Cursor.execute("select col1 from tablename1 order by sequenceid desc").fetchone()
               #convert tuple to srting [0] gives first tuple element. 
               Master_CID_str=str(Master_CID[0])
               #Get GUID by stripping first 2 chars and last char.
               Master_CID_str=Master_CID_str[2:len(Master_CID_str)-1]
               Master_CLID=Master_Cursor.execute("select col2 from tablename2 order by sequenceid desc").fetchone()
               Master_CLID_str=str(Master_CLID[0])
               Master_CLID_str=Master_CLID_str[2:len(Master_CLID_str) - 1]



           # Wait for service that transfers data from one db to another DB to run
               time.sleep(310)
           finally:
                Master_Cursor.close()
                Master_db.close()

           return Master_CID,Master_CID_str,Master_CLID,Master_CLID_str


    def testing_int_instance(self):
           #unpacking return value of tuple from testing_master() function
           Master_CID,Master_CID_str,Master_CLID,Master_CLID_str=self.testing_master()
           print ("printing from testing_int_instance {0}".format(Master_CID))
           Int_Instance_Conn = 'Driver={SQL Server};Server=server2\servername2;Database=database2;UID=uid;PWD=password;'
           Int_db = pyodbc.connect(Int_Instance_Conn)
           Int_Cursor = Int_db.cursor()
           #return Int_db, Int_Cursor
           #execute select from  db where col matches that of one inserted in master db.
           Int_Instance_CID=Int_Cursor.execute("select col1 from table1 where cartridgemodelid = '%s'" %(Master_CID_str)).fetchone()
           print(Int_Instance_CID)
           smtpObj = smtplib.SMTP('22.101.1.333', 25)
           if (Master_CID==Int_Instance_CID):
               print("Matched")
               content="This email confirms successful  data transfer from Master to  Instance for col1: \n"
               message = "\r\n".join(["From:" + sender,"To:" + str(receivers[:]),"Subject: Test Result","",content +Master_CID_str])
               #smtpObj = smtplib.SMTP('22.101.2.222', 25)
               smtpObj.sendmail(sender, receivers, message)
           elif (Master_CID!=Int_Instance_CID):
               print("no match")
               content = "This email confirms failure of  data transfer from DB1 to DB2 for COL1: \n"
               message = "\r\n".join(["From:" + sender, "To:" + str(receivers[:]), "Subject: Test Result", "",content +Master_CID_str])
               smtpObj.sendmail(sender, receivers, message)
           Int_Instance_CLID=Int_Cursor.execute("select COL2 from table2 where col= '%s'" %(Master_CLID_str)).fetchone()
           print (Int_Instance_CLID)
           if (Master_CLID == Int_Instance_CLID):
               print ("Printing int_instance CLID {0}".format(Int_Instance_CLID))
               content = "This email confirms successful data transfer from DB1 to DB2 for COL: \n"
               message = "\r\n".join(
                  ["From:" + sender, "To:" + str(receivers[:]), "Subject: Test Result", "", content + Master_CLID_str])
               #smtpObj = smtplib.SMTP('22.101.2.222', 25)
               smtpObj.sendmail(sender, receivers, message)
               print ("Ids Matched")
           elif (Master_CLID != Int_Instance_CLID):
DB1 to DB2 for COL: \n"
               message = "\r\n".join(
                  ["From:" + sender, "To:" + str(receivers[:]), "Subject: Test Result", "", content + Master_CLID_str])
               #smtpObj = smtplib.SMTP('22.101.2.222', 25)
               smtpObj.sendmail(sender, receivers, message)
           smtpObj.quit()


           Int_db.close()
如果name='main': unittest.main()

add1.sql是:

DECLARE@Name VARCHAR(2000)
声明@PartNumber VARCHAR(2000)
选择@Name='test'+convert(varchar,getdate(),108)
选择@PartNumber='17\u 00001\u'+转换(varchar,getdate(),108)
声明@XML
声明@FileName VARCHAR(1000)
声明@Id唯一标识符
选择@Id=NEWID()
选择@FileName='test.xml'
选择@XML=
开始
插入表1
(ID、名称、类型、描述、编号、版本、型号、状态、修改人、修改人)
值(@Id、@Name、'xyz'、''、@partnumber、'01'、@XML、'A'、'453454-4545-4545-4543-345342343',GETUTCDATE())
add2.sql是:

DECLARE@XML
声明@CM_Name VARCHAR(2000)
声明@FileName VARCHAR(1000)
声明@PartNumber VARCHAR(2000)
声明@Id唯一标识符
选择@Id=NEWID()
声明@Name VARCHAR(2000)
声明@CMId VARCHAR(2000)
声明@CM_PartName VARCHAR(2000)
声明@CM_零件号VARCHAR(2000)
选择@Name='test'+convert(varchar,getdate(),108)
选择@PartNumber='test'+convert(varchar,getdate(),108)
声明@rowcountint
声明@messagevarchar(100);
选择@FileName='test.xml'
选择@CMId=CM.CMId,
@CM_Name=CM.CMName,
@CM_PN=CM.PN
从cm。模型cm
其中CM.MName类似于“test%”
按厘米订购。按描述修改
选择@XML=
其他xml标记。。。
开始
插入cm.CL(ID、模型ID、布局、说明、PN、修订、涂改、状态、修改人、修改人)
选择前1个@Id、@CMId、@Name、@PartNumber、'01'、@XML、'A','453454-345-4534-4534-4534543545',GETUTCDATE()
从厘米到表1厘米
其中CM.Name=@CM\u Name
和CM.Partnumber=@CM\u Partnumber
当前,您正在调用
test\u master()
两次!首先作为命名方法,然后在解包返回值时作为第二个方法。下面是在类对象之外定义的方法的演示。如果按原样调用,测试主机将运行两次

还可以考虑使用上下文管理器,使用
with()
读取.sql脚本,该脚本处理打开和关闭i/o操作,如下所示:

# FIRST CALL
def testing_master():
    #...SAME CODE...
    try:
        with open('C:\\aaa\\add1.sql', 'r') as file:
            lines = file.read().replace('\n', ' ')    
        Master_Cursor.execute(lines)
        Master_db.commit()

        time.sleep(1)

        with open('C:\\aaa\\add2.sql', 'r') as file1:
            lines1 = file1.read().replace('\n', ' ')    
        Master_Cursor.execute(lines1)
        Master_db.commit()

    #...SAME CODE...  
    return Master_CID, Master_CID_str, Master_CLID, Master_CLID_str


def testing_int_instance():
    # SECOND CALL
    Master_CID, Master_CID_str, Master_CLID, Master_CLID_str = testing_master()    
    #...SAME CODE...

if __name__ == "__main__": 
    testing_master()
    testing_int_instance()
注释掉
时间(310)
似乎是可行的,但正如您提到的,后台Windows服务无法有效运行,因此会中断数据库传输

要解决的是,在第一个结束时调用第二个方法,将值作为参数而不使用任何<代码>返回< /代码>,并移除解包行。然后,在主全局环境中,只运行

testing\u master()
。当然,在类定义中使用
self
进行限定

def testing_master():
    #...SAME CODE...
    testing_int_instance(Master_CID, Master_CID_str, Master_CLID, Master_CLID_str)

def testing_int_instance(Master_CID, Master_CID_str, Master_CLID, Master_CLID_str):
    #...SKIP UNPACK LINE 
    #...CONTINUE WITH SAME CODE...

if __name__ == "__main__": 
    testing_master()

由于您的<代码> UNITTest,请考虑对原始设置的轻微调整,在这里您可以用<代码>自身< /代码>限定每个变量:

def testing_master():
    ...
    self.Master_CID=Master_Cursor.execute("select col1 from tablename1 order by sequenceid desc").fetchone()
    self.Master_CID_str=str(Master_CID[0])
    self.Master_CID_str=Master_CID_str[2:len(Master_CID_str)-1]
    self.Master_CLID=Master_Cursor.execute("select col2 from tablename2 order by sequenceid desc").fetchone()
    self.Master_CLID_str=str(Master_CLID[0])
    self.Master_CLID_str=Master_CLID_str[2:len(Master_CLID_str) - 1]

def testing_int_instance(self):
    # NO UNPACK LINE
    # ADD self. TO EVERY Master_* VARIABLE
    ...
目前,您正在调用
test\u master()
两次!首先作为命名方法,然后在解包返回值时作为第二个方法。下面是在类对象之外定义的方法的演示。如果按原样调用,测试主机将运行两次

还可以考虑使用上下文管理器,使用
with()
读取.sql脚本,该脚本处理打开和关闭i/o操作,如下所示:

# FIRST CALL
def testing_master():
    #...SAME CODE...
    try:
        with open('C:\\aaa\\add1.sql', 'r') as file:
            lines = file.read().replace('\n', ' ')    
        Master_Cursor.execute(lines)
        Master_db.commit()

        time.sleep(1)

        with open('C:\\aaa\\add2.sql', 'r') as file1:
            lines1 = file1.read().replace('\n', ' ')    
        Master_Cursor.execute(lines1)
        Master_db.commit()

    #...SAME CODE...  
    return Master_CID, Master_CID_str, Master_CLID, Master_CLID_str


def testing_int_instance():
    # SECOND CALL
    Master_CID, Master_CID_str, Master_CLID, Master_CLID_str = testing_master()    
    #...SAME CODE...

if __name__ == "__main__": 
    testing_master()
    testing_int_instance()
注释掉
时间(310)
似乎是可行的,但正如您提到的,后台Windows服务无法有效运行,因此会中断数据库传输

要解决的是,在第一个结束时调用第二个方法,将值作为参数而不使用任何<代码>返回< /代码>,并移除解包行。然后,在主全局环境中,只运行

testing\u master()
。当然,在类定义中使用
self
进行限定

def testing_master():
    #...SAME CODE...
    testing_int_instance(Master_CID, Master_CID_str, Master_CLID, Master_CLID_str)

def testing_int_instance(Master_CID, Master_CID_str, Master_CLID, Master_CLID_str):
    #...SKIP UNPACK LINE 
    #...CONTINUE WITH SAME CODE...

if __name__ == "__main__": 
    testing_master()

由于您的<代码> UNITTest,请考虑对原始设置的轻微调整,在这里您可以用<代码>自身< /代码>限定每个变量:

def testing_master():
    ...
    self.Master_CID=Master_Cursor.execute("select col1 from tablename1 order by sequenceid desc").fetchone()
    self.Master_CID_str=str(Master_CID[0])
    self.Master_CID_str=Master_CID_str[2:len(Master_CID_str)-1]
    self.Master_CLID=Master_Cursor.execute("select col2 from tablename2 order by sequenceid desc").fetchone()
    self.Master_CLID_str=str(Master_CLID[0])
    self.Master_CLID_str=Master_CLID_str[2:len(Master_CLID_str) - 1]

def testing_int_instance(self):
    # NO UNPACK LINE
    # ADD self. TO EVERY Master_* VARIABLE
    ...

首先,最重要的一点:这些函数在哪里调用?你只能在这里定义它们。请在第二种方法的底部修改代码。第二,除了表之外,没有人写入数据库。哪些表重复这两个脚本的数据?最后,其中一个脚本使用
[TABLENAME]
。这是什么?3)两个表(来自两个插入脚本)重复数据。注意:如果我在testing_master(self)函数中注释out time.sleep(310),它只在每个表中写入一条记录(来自每个插入脚本),我不确定为什么它会随时间写入两次(4条记录到2个表中)。我需要这个,因为我必须等待windows服务运行,我甚至尝试将time.sleep(310)从第一个功能中删除,但这也不起作用。我不能使用拆卸方法来放置time.sleep(310),因为我不希望它在每个函数之后运行。4) 实际表名进入[TABLENAME]。我忘记粘贴调用函数。下面是第二个函数底部的内容。如果name_uuu==“uuuu main”:unittest.main()2)我的意思是说写入“表”而不是“数据库”,我的原始帖子已经更新。由于它确实写入表并发送电子邮件,我怀疑问题是否与函数调用不正确有关。在我看来就像时间。睡眠(310)导致它写两次。如果我对这行进行注释,我的代码就可以正常工作,但正如我所说,我需要在那里等待windows服务运行。如果你是inte