当前位置: 首页 > 科技观察

如何使用Python实现SQL自动化?

时间:2023-03-14 19:07:06 科技观察

我在工作中经常使用SQL,它有令人讨厌的细微差别和局限性,但归根结底,它是数据行业的基石。因此,对于数据领域的每一位工作者来说,SQL都是必不可少的。熟练掌握SQL意义重大。SQL很好,但是我们怎么能满足于“好”呢?为什么不进一步操作SQL?声明式语句会诱发SQL限制的发生,即从SQL中查找数据,SQL会在特定的数据库中查找并返回。这对于许多数据提取或简单的数据操作任务来说已经足够了。但是,如果您需要更多呢?本文将向您展示如何操作。从基础importpyodbcfromdatetimeimportdatetimeclassSql:def__init__(self,database,server="XXVIR00012,55000"):#herewearetellingpythonwhattoconnectto(ourSQLServer)self.cnxn=pyodbc.connect("Driver={SQLServerNativeClient11.0};""Server="+server+";""Database="+database+";""Trusted_Connection=yes;")#initialisequeryattributeself.query="--{}\n\n--MadeinPython".format(datetime.now().strftime("%d/%m/%Y"))这段代码是操作MSSQL服务器的基础。这段代码只要写好,只需要通过Python连接SQL即可:sql=Sql('database123')很简单吧?几件事情同时发生,下面将剖析这段代码。classSql:首先要注意的是这段代码包含在一个类中。作者认为这是合乎逻辑的,因为在这种格式中,已经为这个特定的数据库完成了添加或删除的过程。如果你看到工作过程,你的思路会更清晰。初始化类:def__init__(self,database,server="XXVIR00012,55000"):因为笔者和同事几乎都是连接同一个服务器,所以我把这个常用浏览器的名称设置为默认参数服务器。您可以在“连接到服务器”对话框或MSSQLServerManagementStudio窗口的顶部找到服务器的名称:接下来,连接到SQL:self.cnxn=pyodbc.connect("Driver={SQLServerNativeClient11.0};""Server="+self.server+";""Database="+self.database+";""Trusted_Connection=yes;")pyodbc模块使这一步变得极其简单。只需将连接字符串转换为pyodbc.connect(...)函数,单击此处了解详细信息。最后,我通常在Sql类中写一个查询字符串,它随着传递给该类的每个查询而更新:self.query="--{}\n\n--MadeinPython".format(datetime.now()。strftime("%d/%m/%Y"))这样方便记录代码,也使得输出的可读性更强,让别人读起来更舒服。请注意,在下面的代码片段中,我不会更新代码的self.query部分。分块一些重要的功能非常有用,我几乎每天都用它。这些功能都专注于将数据传入和传出数据库。从下图文件目录开始:对于当前项目,需要:将文件导入SQL合并成一张表根据列中的类别灵活创建多张表SQL类不断丰富后,后续会容易得多:importsyssys.path。插入(0,r'C:\\User\medium\pysqlplus\lib')importosfromdataimportSqlsql=Sql('database123')#initialisetheSqlobjectdirectory=r'C:\\User\medium\data\\'#thisiswhereourgenericdataisstoredfile_list=os.listdir(目录)#getalistofallfilesforfileinfile_list:#looptoimportfilestosqldf=pd.read_csv(目录+文件)#readfiletodataframesql.push_dataframe(df,file[:-4])#nowweconvertourfile_listnamesintothetablenameswehaveimportedtoSQLtable_names=[x[:-4]forxinfile_list]_sql.union,'(generic_jan')#unionourfilesintoonenewtablecalled'generic_jan'sql.drop(table_names)#dropouroriginaltablesaswenowhavefulltable#getlistofcategoriesincolX,例如['hr','finance','tech','c_suite']sets=list(sql.manual(“SELECTcolXAS'category'FROMgeneric_janGROUPBYcolX",response=True)['category'])forcategoryinsets:sql.manual("SELECT*INTOgeneric_jan_"+category+"FROMgeneric_janWHEREcolX='"+category+"'")从零开始输入数据结构defpush_dataframe(self,data,table="raw_data",batchsize=500):#createexecutioncursorcursor=self.cnxn.cursor()#activatefastexecutecursor.fast_executemany=True#createcreatetablestatementquery="CREATETABLE["+table+"](\n"#iteratethrougheachcolumntobeincludedincreatetablestatementforiinrange(len(list(data))):query+="\t[{}]varchar(255)".format(list(data)[i])#addcolumn(everythingisvarcharfornow)#appendcorrectconnection/endstatementcodeifi!=len(list(data))-1:query+=",\n"else:query+="\n);"cursor.execute(query)#executethecreatetablestatementself.cnxn.commit()#commitchanges#appendquerytoourSQLcodeloggerself.query+=("\n\n--createtable\n"+query)#insertthedatainbatchesquery=("INSERTINTO[{}]({})\n".format(table,'['+'],['#getcolumns.join(list(data))+']')+"VALUES\n(?{})".format(",?"*(len(list(data))-1)))#insertdataintotargettableinbatchesof'batchsize'foriinrange(0,len(data),batchsize):ifi+batchsize>len(data):batch=data[i:len(data)].values.tolist()else:batch=data[i:i+batchsize].values.tolist()#executebatchinsertcursor.executemany(query,batch)#commitinserttoSQLServerself.cnxn.commit()这个函数包含在SQL类中,可以方便的将Pandasdataframe插入到SQL数据库中。当需要上传大量文件时非常有用。然而,Python可以将数据插入SQL的真正原因是它的灵活性。在十几个Excel工作簿中插入SQL中的特定标记真是一件令人头疼的事情。但是对于Python,这是小菜一碟。现在我已经构建了一个可以在Python中读取标签并将标签插入到SQL中的函数。手动(函数)defmanual(self,query,response=False):cursor=self.cnxn.cursor()#createexecutioncursoriresponse:returnread_sql(query,self.cnxn)#getsqlqueryoutputtodataframetry:cursor.execute(query)#executeexceptpyodbc.ProgrammingErrorraserror:print(“警告:\n{}”.format(错误))#printerrorasawarningself.cnxn.commit()#commitquerytoSQLServerreturn“查询完成。”这个函数其实用在了union和drop函数中。只是为了尽可能简单地使用SQL代码。响应参数将查询输出解压缩到DataFrame中。generic_jan表中的colX可用于提取所有唯一值。操作如下:sets=list(sql.manual("SELECTcolXAS'category'FROMgeneric_janGROUPBYcolX",response=True)['category'])Union(function)构建手动函数,创建联合函数很简单:defunion(self,table_list,name="union",join="UNION"):#initialisethequeryquery="SELECT*INTO["+name+"]FROM(\n"#buildtheSQLqueryquery+=f'\n{join}\n'。join([f'SELECT[{x}].*FROM[{x}]'forxintable_list])query+=")x"#addendofqueryself.manual(query,fast=True)#fastexecute创建的union函数仅此而已而不是循环引用table_list提出的表名,从而构造对给定表名的UNION函数查询。然后用self.manual(query)处理它。drop(function)是可行的,可以上传大量的表到sqlserver。虽然可行,但它会很快使数据库超载。为了解决这个问题,你需要创建一个drop函数:defdrop(self,tables):#checkifsingleorlistifisinstance(tables,str):#ifsinglestring,converttosingleiteminlistfor-looptables=[tables]fortableintables:#checkforpre-existingtableanddeleteifpresentquery=("IFOBJECT_ID('["+table+"]','U')ISNOTNULL""DROPTABLE["+table+"]")self.manual(query)#executeviewrawpysqlplus_drop_short.py托管在GitHub点击https://gist.github.com/jamescalam/b316c1714c30986fff58c22b00395cc0了解全貌。同样,这个功能也很简单,因为有手动功能。操作员可以选择在表中输入字符来删除单个表,或者向表提供列名列表以删除多个表。当这些非常简单的功能组合在一起时,您可以利用Python极大地丰富SQL的功能。我几乎每天都用这个方法,很简单也很有效。希望能帮助其他用户找到将Python合并到他们的SQL路径中的方法,感谢阅读!