2020-11-27 ubuntu镜像源、pycharm社区版DB Navigator连接mssql、ubuntu下python连接mssql、django连接mssql

写在前面,首先说一下ubuntu apt安装软件时经常出现依赖包缺失的问题,主要原因是apt源与系统版本不对应。登录清华大学的开源软件镜像源网站,选择与自己操作系统版本一致的源,sudo gedit /etc/apt/sources.list,覆盖原内容保存,sudo apt update,再安装之前出问题的包,往往就能成功。

今天主要在填数据库连接的坑,如果是配置管理那些当下流行的数据库,自然不用费这么大劲,但总会有老系统会用到微软的sqlserver,为了兼容历史数据,回避不了从ubuntu系统向windows下的sqlserver请求数据的问题。主要包括两方面,一方面是在ubuntu中远程可视化管理sqlserver数据,一方面是Django项目要对sqlserver进行连接访问。前者可选的方案较多,有贵的有免费的,有好用的也有难用的,重点是要找个物廉价美的。后者没得多选,Django连接mssql,只能通过pyodbc和django-pyodbc-azure,而pyodbc这个插件要想在ubuntu下跑通,有很多坑要填补,甚至花费了我将近两小时找到了pyodbc的一个bug,一抓一把头发啊。

先说简单的,选择一个在ubuntu下可视化管理mssql的物廉价美方案。好用的有大名鼎鼎的navicat,可是不便宜。微软的vscode是免费的,也提供了mssql插件,尝试了半天,可是总在连接建立后的握手阶段发生错误。放弃这个,到pycharm里去配置。具体配置过程如下。

首先到mssql数据库所在的windows系统上查看mssql的网络端口有没有打开,mssql的默认端口是1433,为了提高安全性,也可以通过微软提供的sqlserver配置管理器去更改端口。我这里是测试环境,就不做修改了。打开windows的系统防火墙(右下角网络属性里找高级防火墙功能),在入站规则中新建一个开放1433端口的规则。还不放心,就用cmd中的telnet测试一下1433端口有没有打开。cmd里输入telnet IP 1433,注意端口号前没有冒号,能连接上就说明端口没问题。telnet并不是默认启用的功能,需要到windows的应用程序管理里启用这个windows功能。

数据库配置没问题了,再到ubuntu上配置pycharm的数据库管理工具。我的windows系统下的pycharm是专业版,自带了数据库管理功能,且能直接管理mssql。但ubuntu下这个免费的社区版并不提供这一功能,还好可以安装第三方插件,名字叫DB Navigator,在File->settings->plugins中搜索安装,安装完后重启IDE,就可以在上方看到DB Navigator按钮,点开下拉列表添加数据库连接配置。很不幸的是,毕竟是第三方工具,默认只提供了oracle、mysql、sqllite的连接配置,JDBC连接方式并不是默认的,需要自行配置。

既然是JDBC连接,首先就要去微软官网下载JDBC的jar包,而运行jar包必然要依赖java环境。先查看本机是否已安装java环境,在终端输入java -version,如果能返回版本号,则已经存在java环境,若找不到指令,则需要先安装,sudo apt install default-jdk,安装完毕再次通过java -version查看jdk为11.0版,JDBC最新版8.0支持此jdk,这里给出下载链接(微软JDBC下载路径)。下载后转移到合适的目录,比如项目的根目录处,然后在刚才安装的DB Navigator下拉列表下找到setting,配置一个JDBC的数据库连接,驱动程序选择刚才移动过来的对应jdbc的jar包,注意要与自己java版本对应。输入数据库用户名sa和密码,url填写连接字符串:

jdbc:sqlserver://IP:1433;database=数据库名

测试连接,成功了。以后就可以用DB Navigator的DB Browser直观的管理远程的sqlserver数据库了,这一切都是免费而好用的。

这只解决了一方面问题,pycharm是基于java的IDE环境,自然可以通过JDBC连接数据库。但Django程序是基于python的,python连接微软的sqlserver在windows操作系统上是通过pyodbc插件实现,pyodbc又是基于ODBC,Ubuntu系统对ODBC支持并不好,这里存在一个大坑需要填补。还好微软给出了解决方案(找到这个方案可花了我一番功夫,找到后依葫芦画瓢在终端中运行一遍就ok了)。这里有个curl指令,ubuntu没有默认安装,需要提前sudo apt install curl,这个指令向目的网址发起请求,并将服务器返回的信息输出到终端,当然可以配合很多参数使用。不带参数相当于发送一个get请求。|是管道命令,用于将前一条指令输出的内容转交给后一条指令作为输入。下面这段中的第一个curl就是首先向微软请求一个公钥,并将这个公钥写到apt的key列表中,apt-key函数的第二个参数是输入内容,函数中将这个-指代为标准输入stdin,也就是前面curl输出到通道再输入给apt-key的内容。可以通过apt-key list查看一下保存在本机的apt证书。第二个curl通过输出重定向>将curl取回的prod.list写进/etc下的一个配置文件中。做完这些准备工作,接着安装了msodbcsql17、mssql-tools和unixodbc-dev,并将mssql-tools/bin目录下的mssql命令通过环境变量发布到全局。过程就是这么个过程,主要是把unixodbc-dev这个软件包安装好了,这个软件包直接决定了能否成功安装pyodbc。

sudo su
curl https://packages.microsoft.com/keys/microsoft.asc | apt-key add -
#Ubuntu 20.04
curl https://packages.microsoft.com/config/ubuntu/20.04/prod.list > /etc/apt/sources.list.d/mssql-release.list
exit
sudo apt-get update
sudo ACCEPT_EULA=Y apt-get install msodbcsql17
sudo ACCEPT_EULA=Y apt-get install mssql-tools
echo 'export PATH="$PATH:/opt/mssql-tools/bin"'>> ~/.bash_profile
echo 'export PATH="$PATH:/opt/mssql-tools/bin"'>> ~/.bashrcsource~/.bashrc
sudo apt-get install unixodbc-dev

似乎胜利就在眼前了,但这里先插入一段django项目从windows迁移到ubuntu的波折。之前的django项目是在windows环境下开发的,通过windows端的pycharm连接了到ubuntu下的ftp,将django项目原封不动上传到ubuntu上。在ubuntu上我本想着通过pycharm再导入venv就可以加载原来的虚拟环境,可是pycharm在导入 venv目录下的python解释器时报错,无法加载虚拟环境。打开venv目录一看,这里的python竟然是exe文件,显然不行嘛。只能把这个venv目录删除,通过pycharm重新建了一个虚拟环境。但原来的依赖包怎么办呢?手工一个一个再安装一遍吗?pip工具已经为我们考虑到了这种情况,可以通过pip freeze > requirements.txt 命令,将依赖包关系导入到requirements.txt文件中。显然这个命令是在原windows下的项目虚拟环境中执行,并将得到的这个txt文件上传到ubuntu上。在ubuntu上的pycharm中打开这个文件,pycharm智能检测到其为依赖包关系文件,提示安装requirement插件。安装好后再用鼠标点击该文件,就可以看到Install All packages的选项,执行则可一键安装所有项目依赖包。由于前面已经将unixodbc-dev软件包安装好了,这里一键安装依赖包时就没有报错(你可以想象到我的操作顺序,肯定是在这里出错后才摸索着去安装unixodbc-dev,一正一反一把辛酸泪,一说一听一纸荒唐言。)

虚拟环境也恢复好了,依赖包也安装上了,切换到项目的settings.py文件中修改数据库连接配置,满心欢喜地去启动服务,没成想又遇到了今天的2号坑。为了查看ubuntu上的odbc驱动名称,到终端中输入odbcinst -j,输出了unixodbc的版本信息、驱动配置文件的路径等。打开驱动配置文件/etc/odbcinst.ini,内容如下:

[ODBC Driver 17 for SQL Server]
Description=Microsoft ODBC Driver 17 for SQL Server
Driver=/opt/microsoft/msodbcsql17/lib64/libmsodbcsql-17.6.so.1.1
UsageCount=1

按照这个描述,在django的settings.py中将数据库的driver设置为“ODBC Driver 17 for SQL Server”,sqlserver服务器的IP地址、端口、用户名、密码等都一一填好,本以为稳了,python manage.py runserver 0.0.0.0:8888试一下,报错,找不到ODBC Driver 17 for SQL Server这个驱动。又是一番试错,索性将上面那段unixODBC配置文件中的Driver直接抄到django配置中:"Driver" : "/opt/microsoft/msodbcsql17/lib64/libmsodbcsql-17.6.so.1.1",运行一下,这回不再是驱动找不到的错误了,但出现了[error:1425F102:SSL routines: ssl_choose_client_version: unsupported protocol]这一新的错误。这说明unixODBC已经发挥作用了,连接已经建立,是通信协议的问题。网上搜索了一下这个错误,是openssl版本的问题,ubnutu20.04的OpenSSL升级到了1.1.1f, 将TLS最低版本设置为了1.2,解决问题的最好办法是升级数据库服务器的TLS版本到1.2, 对于无法升级服务器的, 也可以选择降低OpenSSL的TLS版本要求。降级的方法也很简单,打开 /etc/ssl/openssl.cnf , 找到这行

oid_section = new_oids

在这行下面紧接着添加下面几句

openssl_conf= default_conf
[default_conf]
ssl_conf= ssl_sect
[ssl_sect]
system_default= system_default_sect
[system_default_sect]
MinProtocol= TLSv1.1
CipherString= DEFAULT@SECLEVEL=1

重新运行django,天哪,又有新的错误,这回是[ODBC Driver 17 for SQL Server]Neither DSN nor SERVER keyword supplied的错误。错误信息里提示没有SERVER keyword,django数据库配置中有HOST,又添加了一个SERVER属性,但并没有什么用。又经过一番试错,发现在OPTIONS属性下添加'extra_params': "server=IP地址"就解决了这个问题。具体原因,有个老外给出了有点相关的解释:The Windows ODBC Driver Manager is quite fussy about keywords in connection strings. They must be immediately followed by the equal sign, so **SERVER**=...will work, but **SERVER** = ...will not. Its crazy but I managed to solve it by actually passing an option: extra_params:**server**=WHEREYOURSERVERLIVES\DBSERVER 。I am using it pyodbc on django BTW. Must be some bug.

确实是个pyodbc或者是django_pyodbc的一个bug,用这个extra_params可以解决。django中mssql具体的连接配置如下,这是我历尽万难修正出来的,希望对你有用。至此,ubuntu上的django就可以访问windows上的mssql了。


DATABASES = {

'default': {

        'NAME':'你的数据库名',

        'ENGINE':'sql_server.pyodbc',

        'HOST':'你数据库服务器的IP',

        'USER':'sa',

        'PASSWORD':'不告诉你',

        'PORT':'1433',

        'OPTIONS': {

            'driver':'/opt/microsoft/msodbcsql17/lib64/libmsodbcsql-17.6.so.1.1', #这个可以在odbcinst.ini中查看,这个文件的路径可以在终端中输入odbcinst -j查看到。

            'extra_params':"Persist Security Info=False;server=你数据库服务器的IP"

        }

    }

}

但这中降级安全的配置方法感觉不踏实,那就升级mssql的TLS版本吧。历史数据往往都是用的历史版本的mssql,比如mssql2008。不过从mssql备份数据,再卸载老版本,再安装新版本,也不是困难的事情,需要的只是时间。说干就干,windows上换成了mssql2017,ubuntu上将TLS等级再调回去,再次运行django,OK很完美。新数据库里还没有数据,对django中的依赖老数据库的业务一访问就报错了,这是意料之中的,我也不想通过mssql的MSSM管理器去恢复之前备份的数据(其实我没备份,本来也没啥数据,只有表结构而已,我当时就想要试试django的merge功能自动恢复表结构,喜新厌旧是本性)。那就切换到django项目的虚拟环境下(在pycharm中直接打开终端就是虚拟环境),输入python manage.py makemigrations your_app_name,创建数据库迁移文件,然后再 python manage.py migrate将发生变化的迁移文件应用到数据库。有了django,从此告别裸sql,一切都是面向对象的,感觉格局变大了有木有。
今天就搞到这里吧,周末开始研究docker部署了。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,616评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,020评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,078评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,040评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,154评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,265评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,298评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,072评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,491评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,795评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,970评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,654评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,272评论 3 318
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,985评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,223评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,815评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,852评论 2 351

推荐阅读更多精彩内容