我在工作中经常使用SQL,它有令人讨厌的细微差别和局限性,但归根结底,它是数据行业的基石。因此,对于数据领域的每一位工作者来说,SQL都是必不可少的。熟练掌握SQL意义重大。SQL很棒,但是你怎么能仅仅满足于“好”呢?为什么不进一步操作SQL?声明式语句会诱发SQL限制的发生,即从SQL中查找数据,SQL会在特定的数据库中查找并返回。这对于许多数据提取或简单的数据操作任务来说已经足够了。但是,如果有更多需求怎么办?本文将向您展示如何操作。FromthebasicsimportpyodbcfromdatetimeimportdatetimeclassSql:def__init__(self,database,server="XXVIR00012,55000"):#这里我们告诉python要连接到什么(我们的SQLServer)self.cnxn=pyodbc.connect("Driver={SQLServerNativeClient11.0};""Server="+server+";""Database="+database+";""Trusted_Connection=yes;")#初始化查询属性self.query="--{}\n\n--MadeinPython".format(datetime.now().strftime("%d/%m/%Y"))这段代码是操作MSSQLserver的基础。只要写这段代码,只需要通过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.insert(0,r'C:\\User\medium\pysqlplus\lib')importosfromdataimportSqlsql=Sql('database123')#初始化Sqlobjectdirectory=r'C:\\User\medium\data\\'#这是我们通用数据的存储位置file_list=os.listdir(directory)#获取所有文件的列表forfileinfile_list:#循环导入文件到sqldf=pd.read_csv(directory+file)#读取文件到dataframesql.push_dataframe(df,file[:-4])#现在我们将我们的file_list名称转换成我们导入到SQLtable_names=[x[:-4]forxinfile_list]sql.union(table_names,'generic_jan')#将我们的文件合并到一个名为'generic_jan'的新表中sql.drop(table_names)#删除我们的原始表,因为我们现在有完整的表#获取colX中的类别列表,例如['hr','finance','tech','c_suite']sets=list(sql.manual("从generic_janGROUPBYcolX中选择colX作为“类别””,response=True)['category'])forcategoryinsets:sql.manual("SELECT*INTOgeneric_jan_"+category+"FROMgeneric_janWHEREcolX='"+category+"'")从头开始入栈数据结构defpush_dataframe(self,data,table="raw_data",batchsize=500):#创建执行游标cursor=self.cnxn.cursor()#激活快速执行cursor.fast_executemany=True#创建创建表语句query="CREATETABLE["+table+"](\??n"#遍历要包含在createtable语句中的每一列foriinrange(len(list(data))):query+="\t[{}]varchar(255)".format(list(data)[i])#addcolumn(everythingisvarcharfornow)#appendcorrectconnection/endstatementcodeifi!=len(list(data))-1:query+=",\n"否则:查询+="\n";"cursor.execute(query)#执行建表语句self.cnxn.commit()#commitchanges#appendquerytoourSQLcodeloggerself.query+=("\n\n--createtable\n"+query)#批量插入数据query=("INSERTINTO[{}]({})\n".format(table,'['+'],['#获取列.join(list(data))+']')+"VALUES\n(?{})".format(",?"*(len(list(data))-1)))#以'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中的函数。Manual(function)defmanual(self,query,response=False):cursor=self.cnxn.cursor()#创建执行游标ifresponse:returnread_sql(query,self.cnxn)#将sql查询输出到dataframetry:cursor.execute(query)#executeexceptpyodbc.ProgrammingErroraserror:print("Warning:\n{}".format(error))#将错误打印为警告self.cnxn.commit()#将查询提交给SQLServerreturn"Query完全的。”这个函数其实用在了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"):#初始化查询query="SELECT*INTO["+name+"]FROM(\n"#buildtheSQLqueryquery+=f'\n{join}\n'.join([f'SELECT[{x}].*FROM[{x}]'forxintable_list])query+=""x"#添加查询结尾self.manual(query,fast=True)#fastexecutecreatingaunionfunction无非是循环引用table_list提出的表名,为给定的表名构建UNION函数查询。然后用self.manual(query)处理它。drop(function)可行的是上传大量表到sqlserver。虽然可行,但它会很快使数据库超载。为了解决这个问题,你需要创建一个drop函数:defdrop(self,tables):#checkifsingleorlistifisinstance(tables,str):#ifsinglestring,converttosingleiteminlistforfor-looptables=[tables]fortableintables:#检查预先存在的表,如果存在则删除query=("IFOBJECT_ID('["+table+"]','U')ISNOTNULL""DROPTABLE["+table+"]")self.manual(query)#execute同理,这个函数由于有手动函数,所以极其简单。操作员可以选择在表中输入字符来删除单个表,或者向表提供列名列表以删除多个表。当这些非常简单的功能组合在一起时,您可以利用Python极大地丰富SQL的功能。我几乎每天都用这个方法,很简单也很有效。希望能帮助其他用户找到将Python合并到他们的SQL路径中的方法,感谢阅读!文渊网络仅供学习使用,如有侵权,请联系删除。我的公众号【Python圈】汇集了优质的技术文章和经验总结。学习Python的路上肯定会遇到困难,不要慌张,我这里有一套学习资料,包括40+电子书,600+教学视频,涉及Python基础、爬虫、框架、数据分析、机学习等等,别怕学不会!还有学习交流群,一起学习进步~
