【pyodbc】使用Python连接SQL Server查询处理数据

5 篇文章 1 订阅
3 篇文章 1 订阅

更多内容请点击 我的博客 查看,欢迎来访。

以前可以使用pymssql连接微软的SQL Server,但新版的Python不再支持,项目也不再维护。所以转而使用pyodbc

首先MS SQL Server设置可以远程连接,然后分别在Windows和Linux进行连接,读取数据进行处理,最终定时将处理的数据发送到QQ群。

SQL Server允许远程连接配置

创建只读用户

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Jgp1rvi3-1585836392893)(https://blog.starmeow.cn/media/blog/images/2020/04/BLOG_20200402_220015_39.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240 “博客图集BLOG_20200402_220015_39.png”)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9g1IH08y-1585836392894)(https://blog.starmeow.cn/media/blog/images/2020/04/BLOG_20200402_220020_55.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240 “博客图集BLOG_20200402_220020_55.png”)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mQXEi8eT-1585836392895)(https://blog.starmeow.cn/media/blog/images/2020/04/BLOG_20200402_220026_79.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240 “博客图集BLOG_20200402_220026_79.png”)]

允许远程连接到此服务器

右键—属性

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bE4vYCjY-1585836392895)(https://blog.starmeow.cn/media/blog/images/2020/04/BLOG_20200402_220033_76.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240 “博客图集BLOG_20200402_220033_76.png”)]

设置TCP/IP

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ar6Wsjnp-1585836392895)(https://blog.starmeow.cn/media/blog/images/2020/04/BLOG_20200402_220040_30.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240 “博客图集BLOG_20200402_220040_30.png”)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nIDMHRcN-1585836392896)(https://blog.starmeow.cn/media/blog/images/2020/04/BLOG_20200402_220046_70.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240 “博客图集BLOG_20200402_220046_70.png”)]

确定“微软SQL服务器网络选项协议”中的TCP/IP协议对服务器来说是有效的。再次检查是否已经可以执行远程链接。

设置监听IP为本机的

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QhIlj1GQ-1585836392897)(https://blog.starmeow.cn/media/blog/images/2020/04/BLOG_20200402_220056_14.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240 “博客图集BLOG_20200402_220056_14.png”)]

防火墙允许

若“错误提醒对话框”依然弹出,我们需要进一步检查SQL服务器防火墙选项。

允许RemoteAccessEnabled

右击数据库选择“方面”,将“RemoteAccessEnabled”属性设为“True”,点“确定”

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-41pc4bmH-1585836392900)(https://blog.starmeow.cn/media/blog/images/2020/04/BLOG_20200402_220106_43.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240 “博客图集BLOG_20200402_220106_43.png”)]

工具测试连接

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vWJxi0De-1585836392901)(https://blog.starmeow.cn/media/blog/images/2020/04/BLOG_20200402_220115_98.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240 “博客图集BLOG_20200402_220115_98.png”)]

Windows连接

系统版本为Windows10-1909

如何使用ODBC驱动

https://github.com/mkleehammer/pyodbc/wiki/Connecting-to-SQL-Server-from-Windows

Microsoft为SQL Server编写并分发了多个ODBC驱动程序:

  • {SQL Server} - released with SQL Server 2000
  • {SQL Native Client} - released with SQL Server 2005 (also known as version 9.0)
  • {SQL Server Native Client 10.0} - released with SQL Server 2008
  • {SQL Server Native Client 11.0} - released with SQL Server 2012
  • {ODBC Driver 11 for SQL Server} - supports SQL Server 2005 through 2014
  • {ODBC Driver 13 for SQL Server} - supports SQL Server 2005 through 2016
  • {ODBC Driver 13.1 for SQL Server} - supports SQL Server 2008 through 2016
  • {ODBC Driver 17 for SQL Server} - supports SQL Server 2008 through 2019

“SQL Server Native Client …”和以前的驱动程序被弃用,不应该用于新的开发。

安装pyodbc

pip install pyodbc

安装ODBC驱动程序

下载 SQL 服务器的 Microsoft ODBC 驱动程序

安装完后查看驱动

>>> import pyodbc
>>> [x for x in pyodbc.drivers()]
['SQL Server', 'Microsoft Access Driver (*.mdb, *.accdb)', 'Microsoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb)', 'Microsoft Access Text Driver (*.txt, *.csv)', 'SQL Server Native Client 10.0', 'ODBC Driver 17 for SQL Server']

Windows连接SQL Server

Python Shell中测试

import pyodbc


driver = "{ODBC Driver 17 for SQL Server}"
server = "10.168.2.252"  # 数据库服务器名称或IP
username = "donghuan"  # 用户名
password = "***password***"  # 密码
database = "myserver"  # 数据库名称
port = 1433

# 连接到SQL Server
conn = pyodbc.connect('DRIVER={};SERVER={};DATABASE={};UID={};PWD={}'.format(driver, server, database, username, password))
cursor = conn.cursor()

cursor.execute("SELECT insname, insunit, hvalue, hvaluen FROM myserver.dbo.JfDevIns WHERE insname LIKE '%6楼机房%'")

# 读取所有结果
all_data = cursor.fetchall()
print(all_data)

# 一行一行读取
# row = cursor.fetchone()
# print(row)
# while row:
#     row = cursor.fetchone()
#     print(row)

# 关闭连接
conn.close()

Linux连接

系统版本为Debian8

https://github.com/mkleehammer/pyodbc/wiki/Install

https://github.com/mkleehammer/pyodbc/wiki/Connecting-to-SQL-Server-from-Linux

安装ODBC驱动

微软提供了安装到各种基于Linux/UNIX的平台最新的ODBC驱动程序的说明,例如Debian安装

(ITNest) root@PxeCtrlSys:/home/user/software# curl https://packages.microsoft.com/keys/microsoft.asc | apt-key add -

# Debian8安装
(ITNest) root@PxeCtrlSys:/home/user/software# curl https://packages.microsoft.com/config/debian/8/prod.list > /etc/apt/sources.list.d/mssql-release.list

(ITNest) root@PxeCtrlSys:/home/user/software# apt-get update

(ITNest) root@PxeCtrlSys:/home/user/software# ACCEPT_EULA=Y apt-get install msodbcsql17

# 可选:用于bcp和sqlcmd
(ITNest) root@PxeCtrlSys:/home/user/software# ACCEPT_EULA=Y apt-get install mssql-tools

(ITNest) root@PxeCtrlSys:/home/user/software# echo 'export PATH="$PATH:/opt/mssql-tools/bin"' >> ~/.bash_profile
(ITNest) root@PxeCtrlSys:/home/user/software# echo 'export PATH="$PATH:/opt/mssql-tools/bin"' >> ~/.bashrc
(ITNest) root@PxeCtrlSys:/home/user/software# source ~/.bashrc

# 可选:用于unixODBC开发头文件(安装太慢了)
(ITNest) root@PxeCtrlSys:/home/user/software# apt-get install unixodbc-dev

# 可选:用于debian-slim发行版的kerberos库
(ITNest) root@PxeCtrlSys:/home/user/software# apt-get install libgssapi-krb5-2

驱动程序版本查看

驱动程序版本可以通过检查系统中的odbcinst.ini文件找到,该文件是 Microsoft 的 ODBC 驱动程序安装程序注册自己的位置。

(ITNest) root@PxeCtrlSys:/home/user/software# find / -name odbcinst.ini
/usr/local/etc/odbcinst.ini
/usr/lib/hive/lib/native/hiveodbc/Setup/odbcinst.ini
/opt/microsoft/msodbcsql17/etc/odbcinst.ini
/etc/odbcinst.ini

(ITNest) root@PxeCtrlSys:/home/user/software# cat /etc/odbcinst.ini
(ITNest) root@PxeCtrlSys:/home/user/software# cat /usr/local/etc/odbcinst.ini
[ODBC Driver 17 for SQL Server]
Description=Microsoft ODBC Driver 17 for SQL Server
Driver=/opt/microsoft/msodbcsql17/lib64/libmsodbcsql-17.5.so.2.1
UsageCount=1

Linux使用DSN连接SQL Server

创建DSN配置文件

创建用于将ODBC DSN(数据源名称)定义到数据库的临时文本文件,如下所示:

(ITNest) root@PxeCtrlSys:/home/user/software# vim odbc_dsn.conf

# 添加下面的内容
[MSSQLServerDatabase]
Driver      = ODBC Driver 17 for SQL Server
Description = Connect to my SQL Server instance
Trace       = No
Server      = 10.168.2.252

如果不使用默认的端口1433,需要指定,使用,分隔

Server      = 10.168.2.252,1433

在该文件中,按照上面的格式写,除非具有正确的驱动程序版本。在上面已经通过查看odbcinst.ini确定驱动程序版本。

!使用驱动程序名称与显示在方括号内的应完全相同。

创建DSN

保存临时配置文件odbc_dsn.conf后,可以使用以下命令创建一个“System DSN”:

创建System DSN

# 在 /etc/odbc.ini 中注册SQL Server数据库DSN信息
(ITNest) root@PxeCtrlSys:/home/user/software# odbcinst -i -s -f odbc_dsn.conf -l

# 检查DSN安装:应该包含一个名为[MSSQLServerDatabase]的部分
(ITNest) root@PxeCtrlSys:/home/user/software# cat /etc/odbc.ini
# 如果没有内容就需要另外的方式

创建User DSN

# 在 ~/.odbc.ini 中注册SQL Server数据库DSN信息
(ITNest) root@PxeCtrlSys:/home/user/software# odbcinst -i -s -f odbc_dsn.conf -h

# 检查DSN安装
(ITNest) root@PxeCtrlSys:/home/user/software# cat ~/.odbc.ini
[MSSQLServerDatabase]
Driver=ODBC Driver 17 for SQL Server
Description=Connect to my SQL Server instance
Trace=No
Server=10.168.2.252

出现[MSSQLServerDatabase]的配置,表明生成成功

连接SQL Server

使用python连接

import pyodbc


username = "donghuan"  # 用户名
password = "***password***"  # 密码
database = "myserver"  # 数据库名称
port = 1433

conn = pyodbc.connect('DSN=MSSQLServerDatabase;UID={};PWD={};DATABASE={}'.format(username, password, database))

cursor = conn.cursor()

cursor.execute("SELECT insname, insunit, hvalue, hvaluen FROM myserver.dbo.JfDevIns WHERE insname LIKE '%6楼机房%'")

all_data = cursor.fetchall()
print(all_data)

conn.close()

Linux连接SQL Server

同“Windows连接SQL Server”一样,只要安装了ODBC Driver 17 for SQL Server都可以使用

import pyodbc


driver = "{ODBC Driver 17 for SQL Server}"
server = "10.168.2.252"  # 数据库服务器名称或IP
username = "donghuan"  # 用户名
password = "***password***"  # 密码
database = "myserver"  # 数据库名称
port = 1433

# 连接到SQL Server
conn = pyodbc.connect('DRIVER={};SERVER={};DATABASE={};UID={};PWD={}'.format(driver, server, database, username, password))
cursor = conn.cursor()

cursor.execute("SELECT insname, insunit, hvalue, hvaluen FROM myserver.dbo.JfDevIns WHERE insname LIKE '%6楼机房%'")

# 读取所有结果
all_data = cursor.fetchall()
print(all_data)

# 关闭连接
conn.close()

定时监测动环温度

Python实现QQ发送

创建的名称为:dh_sys_msg.py

"""
动环系统定义推送消息,
使用Linux定时任务,从动环主机上的SQL Server获取数据,取平均值发送QQ消息
"""

import pyodbc


class DonghuanAvg(object):
    def __init__(self, location):
        driver = "{ODBC Driver 17 for SQL Server}"
        server = "10.168.2.252"  # 数据库服务器名称或IP
        username = "donghuan"  # 用户名
        password = "***password***"  # 密码
        database = "myserver"  # 数据库名称
        port = 1433
        self.conn = pyodbc.connect('DRIVER={};SERVER={};DATABASE={};UID={};PWD={}'.format(driver, server, database, username, password))
        self.cursor = self.conn.cursor()
        self.location = location

    def avg_t_and_h(self):
        self.cursor.execute(f"""
        SELECT
            insname,
            insunit,
            hvalue,
            hvaluen
        FROM
            myserver.dbo.JfDevIns
        WHERE
            insname LIKE '%{self.location}%'
        """)

        all_data = self.cursor.fetchall()
        # print(all_data)
        temperature = []
        humidity = []
        for data in all_data:
            if 0 < float(data[2]) < 100:  # 处理检测的异常值,比如1楼机房温度1偶尔为3328.00℃
                if '温度' in data[0]:
                    temperature.append(data)
                if '湿度' in data[0]:
                    humidity.append(data)
        # print(temperature, humidity)

        if len(temperature) != 0:
            avg_temperature = sum(float(v[2]) for v in temperature) / len(temperature)
        else:
            avg_temperature = 0
        if len(humidity) != 0:
            avg_humidity = sum(float(v[2]) for v in humidity) / len(humidity)
        else:
            avg_humidity = 0
        # print(avg_temperature, avg_humidity)

        self.conn.close()
        return round(avg_temperature, 1), round(avg_humidity, 1)

    def format_print(self):
        avg_temperature, avg_humidity = self.avg_t_and_h()
        return "{}平均温度:{}℃,平均湿度:{}%".format(self.location, avg_temperature, avg_humidity)


# 运行时,向QQ群发送消息
def send_lyf_qq_group(msg):
    import requests
    try:
        requests.get('http://***qqbot_server_ip_port**/send_group_msg?group_id=***qq_group_id**', params={'message': str(msg).strip()}, timeout=1)
    except:
        pass


if __name__ == '__main__':
    locations = [str(num) + "楼机房" for num in range(1, 7)]
    msg = ''
    for location in locations:
        obj = DonghuanAvg(location)
        msg += obj.format_print() + '\n'

    print(msg)
    send_lyf_qq_group(msg)

Linux定时消息

(ITNest) root@PxeCtrlSys:/home/user/software# crontab -e
# 添加

# 动环系统顶是消息推送,每天10:10发送温湿度QQ消息
10 10     * * *    /root/.pyenv/versions/ITNest/bin/python /home/user/ITNest/dh_sys_msg.py 2>&1

重启加载或重启cron

(ITNest) root@PxeCtrlSys:/home/user/software# /etc/init.d/cron  reload
[ ok ] Reloading configuration files for periodic command scheduler: cron.
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值