ubuntu下快速搭建docker环境训练yolov5数据集
参考文档
yolov5-github
yolov5-github-训练文档
csdn训练博客
一、配置环境
1.1 安装依赖包
前往清华源官方地址 选择适合自己的版本替换自己的源
# 备份源文件
sudo cp /etc/apt/sources.list /etc/apt/sources.list_bak
# 修改源文件
# 更新
sudo apt update && sudo apt upgrade -y
安装必要的环境依赖包
sudo apt-get install -y build-essential ubuntu-drivers-common net-tools python3 python-is-python3 python3-pip
# 修改pip源为清华源
pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
或者修改配置文件替换pipe国内源地址
mkdir ~/.pip/
cd ~/.pip/
sudo vi pip.conf
输入以下内容:
[global]
index-url = https://pypi.tuna.tsinghua.edu.cn/simple
[install]
trusted-host=pypi.tuna.tsinghua.edu.cn
执行验证:
pip config list
1.2 安装docker
具体安装步骤参考ubuntu安装docker官方文档
-
卸载所有冲突包
for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done -
设置 Docker 的
apt存储库# Add Docker's official GPG key: sudo apt-get update sudo apt-get install -y ca-certificates curl gnupg sudo install -m 0755 -d /etc/apt/keyrings sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg sudo chmod a+r /etc/apt/keyrings/docker.gpg# Add the repository to Apt sources: echo \"deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \"$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \sudo tee /etc/apt/sources.list.d/docker.list > /dev/null sudo apt-get update -
安装最新的docker包
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
1.3 拉取pytorch docker镜像
前往pytorch 官方docker镜像寻找自己合适版本,yolov5要求1.8以上版本,我拉取1.13版本,执行命令:
sudo docker pull pytorch/pytorch:1.13.1-cuda11.6-cudnn8-runtime
1.4 安装nvidia驱动
桌面版参考链接
服务器版参考链接
我们使用pytorch-docker环境无需安装cuda,NVIDIA驱动简单安装如下
-
禁用nouveau驱动
编辑
/etc/modprobe.d/blacklist-nouveau.conf文件,添加以下内容:blacklist nouveau blacklist lbm-nouveau options nouveau modeset=0 alias nouveau off alias lbm-nouveau off -
关闭nouveau
echo options nouveau modeset=0 | sudo tee -a /etc/modprobe.d/nouveau-kms.conf -
重新生成内核并重启
sudo update-initramfs -u sudo reboot -
重启后验证
重启后,执行:lsmod | grep nouveau。如果没有屏幕输出,说明禁用nouveau成功 -
查找推荐驱动
ubuntu-drivers devices # 输出如下 # modalias : pci:v000010DEd00001EB8sv000010DEsd000012A2bc03sc02i00 # vendor : NVIDIA Corporation # model : TU104GL [Tesla T4] # driver : nvidia-driver-450-server - distro non-free # driver : nvidia-driver-525-server - distro non-free # driver : nvidia-driver-535-server - distro non-free # driver : nvidia-driver-418-server - distro non-free # driver : nvidia-driver-525 - distro non-free # driver : nvidia-driver-470 - distro non-free # driver : nvidia-driver-470-server - distro non-free # driver : nvidia-driver-535 - distro non-free recommended # driver : xserver-xorg-video-nouveau - distro free builtin -
安装推荐的驱动程序
根据自己系统选择安装,安装完成后重启
sudo apt install nvidia-driver-535-server -
重启后验证
nvidia-smi命令能够输出显卡信息则验证成功
1.5 安装nvidia docker gpus工具
为了让docker支持nvidia显卡,英伟达公司开发了nvidia-docker,该软件是对docker的包装,使得容器能够看到并使用宿主机的nvidia显卡。
根据网上的资料,从docker 19版本之后,nvidia-docker成为了过去式。不需要单独去下nvidia-docker这个独立的docker应用程序,也就是说gpu docker所需要的Runtime被集成进docker中,使用的时候用–gpus参数来控制。以下是工具安装步骤:
# step1 添加包存储库,在终端依次输入以下命令:
distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add -
curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | sudo tee /etc/apt/sources.list.d/nvidia-docker.list# step2 下载安装nvidia-container-toolkit包
sudo apt-get update && sudo apt-get install -y nvidia-container-toolkit# step3 重启docker服务
sudo systemctl restart docker
二、训练数据集
2.1 下载yolov5代码
前往github下载代码,或者准备自己的yolov5训练代码,如果是拷贝他人代码,将**.git目录删除**,否则后续训练时检查git信息会报错。
git clone git@github.com:ultralytics/yolov5.git
2.2 启动进入pytorch-docker
# 映射宿主机地址到docker内部,根据显卡实际情况指定显存容量
sudo docker run -v /home/zmj/lishi:/workspace --gpus all --shm-size 18g -p 6006:6006 -it pytorch/pytorch:1.13.1-cuda11.6-cudnn8-runtime /bin/bash
后续都将在docker中执行;
2.3 安装依赖项
在docker下进入yolov5代码目录下将request.txt的opencv注释掉然后执行依赖项安装

pip3 install -r requirements.txt -i http://mirrors.aliyun.com/pypi/simple/ --trusted-host mirrors.aliyun.com
继续安装opencv-python-headless版本opencv;
pip3 install opencv-python-headless
2.4 创建文件
2.4.1 数据集为图片+xml格式
将标准好的图像文件夹命名为images,标签文件夹命名为Annotations都放到源码目录的data文件夹下(注意: images内为数据集原始图片,Annotations内为标注的xml文件,对这两个文件夹做好备份);
├── data
│ ├── Annotations 进行 detection 任务时的标签文件,xml 形式,文件名与图片名一一对应
│ ├── images 存放 .jpg 格式的图片文件
│ ├── ImageSets 存放的是分类和检测的数据集分割文件,包含train.txt, val.txt,trainval.txt,test.txt
│ ├── labels 存放label标注信息的txt文件,与图片一一对应├── ImageSets(train,val,test建议按照8:1:1比例划分)
│ ├── train.txt 写着用于训练的图片名称
│ ├── val.txt 写着用于验证的图片名称
│ ├── trainval.txt train与val的合集
│ ├── test.txt 写着用于测试的图片名称
在yolov5根目录下创建make_txt.py文件,内容如下:
import os
import random# 函数:确保文件夹存在,如果不存在则创建
def ensure_folder_exists(folder):if not os.path.exists(folder):os.makedirs(folder)print(f"Created folder: {folder}")# 检查并创建所需文件夹
folders = ["data/ImageSets", "data/JPEGImages", "data/labels"]
for folder in folders:ensure_folder_exists(folder)trainval_percent = 0.1
train_percent = 0.9
xmlfilepath = 'data/Annotations'
txtsavepath = 'data/ImageSets'
total_xml = os.listdir(xmlfilepath)
num = len(total_xml)
list = range(num)
tv = int(num * trainval_percent)
tr = int(tv * train_percent)
trainval = random.sample(list, tv)
train = random.sample(trainval, tr)
file_paths = []
file_paths.append(os.path.join(txtsavepath, 'trainval.txt'))
file_paths.append(os.path.join(txtsavepath, 'test.txt'))
file_paths.append(os.path.join(txtsavepath, 'train.txt'))
file_paths.append(os.path.join(txtsavepath, 'val.txt'))for file_path in file_paths:with open(file_path, 'w') as file:for i in list:name = total_xml[i][:-4] + '\n'if i in trainval:if file_path.endswith('trainval.txt'):file.write(name)if i in train:if file_path.endswith('test.txt'):file.write(name)else:if file_path.endswith('val.txt'):file.write(name)else:if file_path.endswith('train.txt'):file.write(name)file.close()os.chmod(file_path, 0o666) # 设置文件权限print("Finished!")
创建voc_label.py内容如下:
import xml.etree.ElementTree as ET
import pickle
import os
from os import listdir, getcwd
from os.path import join# 函数:确保文件夹存在,如果不存在则创建
def ensure_folder_exists(folder):if not os.path.exists(folder):os.makedirs(folder)print(f"Created folder: {folder}")# 检查并创建所需文件夹
folders = ["data/ImageSets", "data/JPEGImages", "data/labels"]
for folder in folders:ensure_folder_exists(folder)sets = ['train', 'test','val']
#此处修改为实际标注内容
classes = ['fall']
def convert(size, box):dw = 1. / size[0]dh = 1. / size[1]x = (box[0] + box[1]) / 2.0y = (box[2] + box[3]) / 2.0w = box[1] - box[0]h = box[3] - box[2]x = x * dww = w * dwy = y * dhh = h * dhreturn (x, y, w, h)
def convert_annotation(image_id):in_file = open('data/Annotations/%s.xml' % (image_id))file_path = 'data/labels/%s.txt' % (image_id)tree = ET.parse(in_file)root = tree.getroot()size = root.find('size')w = int(size.find('width').text)h = int(size.find('height').text)if(w==0 or h==0):in_file.close()print(image_id,"w ", w, "h ", h, "0 error")image_file = 'data/images/%s.jpg' % (image_id)xml_file = 'data/Annotations/%s.xml' % (image_id)os.remove(image_file)os.remove(xml_file)returnout_file = open('data/labels/%s.txt' % (image_id), 'w')for obj in root.iter('object'):difficult = obj.find('difficult').textcls = obj.find('name').textif cls not in classes or int(difficult) == 1:continuecls_id = classes.index(cls)xmlbox = obj.find('bndbox')b = (float(xmlbox.find('xmin').text), float(xmlbox.find('xmax').text), float(xmlbox.find('ymin').text),float(xmlbox.find('ymax').text))bb = convert((w, h), b)out_file.write(str(cls_id) + " " + " ".join([str(a) for a in bb]) + '\n')in_file.close()out_file.close()os.chmod(file_path, 0o666) # 设置文件权限
wd = getcwd()
print(wd)
for image_set in sets:if not os.path.exists('data/labels/'):os.makedirs('data/labels/')image_ids = open('data/ImageSets/%s.txt' % (image_set)).read().strip().split()file_path = 'data/%s.txt' % (image_set)with open(file_path, 'w') as list_file:for image_id in image_ids:list_file.write('data/images/%s.jpg\n' % (image_id))convert_annotation(image_id)list_file.close()os.chmod(file_path, 0o666) # 设置文件权限
print("Finished!")
依次执行上述两个脚本,如果执行voc_labels.py提示有w 0 h 0 errror字样,说明标注的宽高有0异常,脚本会删除异常标签和图片,需要重新执行这两个脚本。
python3 make_txt.py
python3 voc_label.py
执行完成后会在data下创建ImageSets文件夹和labels文件夹大致内容如下:


data下生成三个txt文件

2.4.2 数据集为图片+txt格式
如果数据集为已经归一化后的txt格式数据,则只需将数据集的train,val,test三个文件夹放到data目录下,使用python在data目录下生成对应的txt文件即可。python实现可参考如下内容:
# chat-gpt编写
import osdef create_list(data_folder, subset):images_folder = os.path.join(data_folder, subset, 'images')list_file_path = os.path.join(data_folder, f'{subset}.txt')with open(list_file_path, 'w') as list_file:for image_name in os.listdir(images_folder):if image_name.endswith('.jpg'):image_path = os.path.relpath(os.path.join(images_folder, image_name), start=os.path.dirname(data_folder))list_file.write(image_path + '\n')# 设置文件权限为0666os.chmod(list_file_path, 0o666)# 替换为您的data目录的路径
data_directory = 'data'# 为train, test, val创建列表
for subset in ['train', 'test', 'val']:create_list(data_directory, subset)
执行之后即可,效果如下:


2.5 修改yaml文件
复制data目录下的coco.yaml,我这里命名为fall.yaml,参照参考文档主要修改三个地方:
-
修改train,val,test的路径为自己刚刚生成的三个txt文件相对于yolov5源码根目录的路径;
-
nc 里的数字代表数据集的类别,我这里只有跌倒一类,所以修改为1;
-
names 里为自己数据集标注的类名称,我这里是
fall;内容如下
# YOLOv5 🚀 by Ultralytics, AGPL-3.0 license # COCO 2017 dataset http://cocodataset.org by Microsoft # Example usage: python train.py --data coco.yaml # parent # ├── yolov5 # └── datasets # └── coco ← downloads here (20.1 GB)# Train/val/test sets as 1) dir: path/to/imgs, 2) file: path/to/imgs.txt, or 3) list: [path/to/imgs1, path/to/imgs2, ..] # path: ../datasets/coco # dataset root dir # train: train2017.txt # train images (relative to 'path') 118287 images # val: val2017.txt # val images (relative to 'path') 5000 images test: data/test.txt # dataset root dir train: data/train.txt # train images (relative to 'path') 128 images val: data/val.txt # val images (relative to 'path') 128 images # test: test-dev2017.txt # 20288 of 40670 images, submit to https://competitions.codalab.org/competitions/20794nc: 1 # number of classes names: ['fall'] # class names# Download script/URL (optional) download: |from utils.general import download, Path# Download labelssegments = False # segment or box labelsdir = Path(yaml['path']) # dataset root dirurl = 'https://github.com/ultralytics/yolov5/releases/download/v1.0/'urls = [url + ('coco2017labels-segments.zip' if segments else 'coco2017labels.zip')] # labelsdownload(urls, dir=dir.parent)# Download dataurls = ['http://images.cocodataset.org/zips/train2017.zip', # 19G, 118k images'http://images.cocodataset.org/zips/val2017.zip', # 1G, 5k images'http://images.cocodataset.org/zips/test2017.zip'] # 7G, 41k images (optional)download(urls, dir=dir / 'images', threads=3)
2.6 修改模型文件
models下有5个模型,smlx需要训练的时间依次增加,按照需求选择一个文件进行修改即可,我选择yolov5s.yaml,只需将nc改为实际值即可;

2.7修改训练tran.py
这里需要对train.py文件内的参数进行修改,weights,cfg,data按照自己所需文件的路径修改,weights如果使用参考博客的文件,将yolov5s.pt下载放到代码根目录下即可,如果使用官方则无需修改,会自行下载。具体参数含义,查看官方文档。我修改内容如下:

2.8 开始训练
执行python train.py
可能报以下错误:

按照提示执行export GIT_PYTHON_REFRESH=quiet继续执行训练命令,就可以开始训练了。
2.9 验证训练结果
训练结束后在代码根目录下执行检测命令,可以将待检测图片放到data/samples目录下执行
python detect.py --weights runs/train/exp/weights/best.pt --source data/samples/ --device 0 --data data/fall.yaml
注意: 每训练一次都会在runs/train/目录下新创建一个exp加数字文件夹,运行测试用例时选择最新的,测试结果也会保存在runs/detect目录下最新的exp文件夹下
相关文章:
ubuntu下快速搭建docker环境训练yolov5数据集
参考文档 yolov5-github yolov5-github-训练文档 csdn训练博客 一、配置环境 1.1 安装依赖包 前往清华源官方地址 选择适合自己的版本替换自己的源 # 备份源文件 sudo cp /etc/apt/sources.list /etc/apt/sources.list_bak # 修改源文件 # 更新 sudo apt update &&a…...
SpringMVC常用注解和用法总结
目标: 1. 熟悉使用SpringMVC中的常用注解 目录 前言 1. Controller 2. RestController 3. RequestMapping 4. RequestParam 5. PathVariable 6. SessionAttributes 7. CookieValue 前言 SpringMVC是一款用于构建基于Java的Web应用程序的框架,它通…...
webpack如何处理css
一、准备工作 新建目录 添加样式 .word {color: red; } index.js添加dom元素,添加一个css word import ./css/index.css;const div document.createElement("div"); div.innerText "hello word!!!"; div.className "word"; do…...
IELTS学习笔记_grammar_新东方
参考: 新东方 田静 语法 目录: 导学简单句… x.1 导学 学语法以应用为主。 基础为:单词,语法 进阶为:听说读写译,只考听说读写。 words -> chunks -> sentences, chunks(语块的重要…...
【计算机组成原理】存储器知识
目录 1、存储器分类 1.1、按存储介质分类 1.2、按存取方式分类 1.3、按信息的可改写性分类 1.4、按信息的可保存性分类 1.5、按功能和存取速度分类 2、存储器技术指标 2.1、存储容量 2.2、存取速度 3、存储系统层次结构 4、主存的基本结构 5、主存中数据的存放 5.…...
vscode配置代码片段
1.ctrl shift p 然后选择 Snippets:Configure User Snippets (配置用户代码片段) 2.选择vue或者vue.json 3.下面为json内容 { “vue-template”: { “prefix”: “modal-table”, “body”: [ “”, " <a-modal v-model:visible“visible” wi…...
vite脚手架,手写实现配置动态生成路由
参考文档 vite的glob-import vue路由配置基本都是重复的代码,每次都写一遍挺难受,加个页面就带配置下路由 那就利用 vite 的 文件系统处理啊 先看实现效果 1. 考虑怎么约定路由,即一个文件夹下,又有组件,又有页面&am…...
解决浏览器缓存问题
1.index.html文件meta标签添加属性 <meta name"viewport" content"widthdevice-width,initial-scale1.0, maximum-scale1.0, minimum-scale1.0, user-scalableno" viewport-fitcover >2.提前main.html处理逻辑再跳转到index.html页 <script>…...
【数据中台】开源项目(2)-Davinci可视应用平台
1 平台介绍 Davinci 是一个 DVaaS(Data Visualization as a Service)平台解决方案,面向业务人员/数据工程师/数据分析师/数据科学家,致力于提供一站式数据可视化解决方案。既可作为公有云/私有云独立部署使用,也可作为…...
Java实现简单飞翔小鸟游戏
一、创建新项目 首先创建一个新的项目,并命名为飞翔的鸟。 其次在飞翔的鸟项目下创建一个名为images的文件夹用来存放游戏相关图片。 用到的图片如下:0~7: bg: column: gameover: ground: st…...
numpy实现神经网络
numpy实现神经网络 首先讲述的是神经网络的参数初始化与训练步骤 随机初始化 任何优化算法都需要一些初始的参数。到目前为止我们都是初始所有参数为0,这样的初始方法对于逻辑回归来说是可行的,但是对于神经网络来说是不可行的。如果我们令所有的初始…...
Bean的加载控制
Bean的加载控制 文章目录 Bean的加载控制编程式注解式ConditionalOn*** 编程式 public class MyImportSelector implements ImportSelector {Overridepublic String[] selectImports(AnnotationMetadata annotationMetadata) {try {Class<?> clazz Class.forName("…...
使用 OpenCV 识别和裁剪黑白图像上的白色矩形--含源码
为了仅获取具有特定边框颜色的矩形,我寻求一种替代识别图像中的轮廓和所有矩形的传统方法。如示例图片所示,我有兴趣使用 opencv 仅获取白色边框矩形的坐标。任何这方面的建议将不胜感激。到目前为止,我的代码已产生如下所示的输出。我的下一个目标是将图像裁剪到大的中心框…...
LeetCode 每日一题 Day1
1094. 拼车 车上最初有 capacity 个空座位。车 只能 向一个方向行驶(也就是说,不允许掉头或改变方向) 给定整数 capacity 和一个数组 trips , trip[i] [numPassengersi, fromi, toi] 表示第 i 次旅行有 numPassengersi 乘客,接…...
【hacker送书活动第7期】Python网络爬虫入门到实战
第7期图书推荐 内容简介作者简介大咖推荐图书目录概述参与方式 内容简介 本书介绍了Python3网络爬虫的常见技术。首先介绍了网页的基础知识,然后介绍了urllib、Requests请求库以及XPath、Beautiful Soup等解析库,接着介绍了selenium对动态网站的爬取和S…...
【算法】希尔排序
目录 1. 说明2. 举个例子3. java代码示例4. java示例截图 1. 说明 1.希尔排序是直接插入排序的一种改进,其本质是一种分组插入排序 2.希尔排序采取了分组排序的方式 3.把待排序的数据元素序列按一定间隔进行分组,然后对每个分组进行直接插入排序 4.随着间…...
四、Zookeeper节点类型
目录 1、临时节点 2、永久节点 Znode有两种,分别为临时节点和永久节点。 节点的类型在创建时即被确定,并且不能改变。 1、临时节点 临时节点的生命周期依赖于创建它们的会话。一旦会话结束,临时节点将被自动删除,...
arcgis导出某个属性的栅格
选中栅格特定属性想要导出时,无法选中“所选图形” 【方法】spatial analyst 工具——提取分析——按属性提取...
计算机网络——传输层
传输层的基本单位是报文; 一、传输层的基本概念 传输层提供端到端的服务; 从通信和信息处理的角度看,传输层向上层应用层提供通信服务; (一)端口号 协议作用端口号FTP文件传输协议21连接;2…...
策略设计模式
package com.jmj.pattern.strategy;public interface Strategy {void show(); }package com.jmj.pattern.strategy;public class StrategyA implements Strategy{Overridepublic void show() {System.out.println("买一送一");} }package com.jmj.pattern.strategy;p…...
【Python】 -- 趣味代码 - 小恐龙游戏
文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...
golang循环变量捕获问题
在 Go 语言中,当在循环中启动协程(goroutine)时,如果在协程闭包中直接引用循环变量,可能会遇到一个常见的陷阱 - 循环变量捕获问题。让我详细解释一下: 问题背景 看这个代码片段: fo…...
Cinnamon修改面板小工具图标
Cinnamon开始菜单-CSDN博客 设置模块都是做好的,比GNOME简单得多! 在 applet.js 里增加 const Settings imports.ui.settings;this.settings new Settings.AppletSettings(this, HTYMenusonichy, instance_id); this.settings.bind(menu-icon, menu…...
第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明
AI 领域的快速发展正在催生一个新时代,智能代理(agents)不再是孤立的个体,而是能够像一个数字团队一样协作。然而,当前 AI 生态系统的碎片化阻碍了这一愿景的实现,导致了“AI 巴别塔问题”——不同代理之间…...
Neo4j 集群管理:原理、技术与最佳实践深度解析
Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...
【python异步多线程】异步多线程爬虫代码示例
claude生成的python多线程、异步代码示例,模拟20个网页的爬取,每个网页假设要0.5-2秒完成。 代码 Python多线程爬虫教程 核心概念 多线程:允许程序同时执行多个任务,提高IO密集型任务(如网络请求)的效率…...
佰力博科技与您探讨热释电测量的几种方法
热释电的测量主要涉及热释电系数的测定,这是表征热释电材料性能的重要参数。热释电系数的测量方法主要包括静态法、动态法和积分电荷法。其中,积分电荷法最为常用,其原理是通过测量在电容器上积累的热释电电荷,从而确定热释电系数…...
【p2p、分布式,区块链笔记 MESH】Bluetooth蓝牙通信 BLE Mesh协议的拓扑结构 定向转发机制
目录 节点的功能承载层(GATT/Adv)局限性: 拓扑关系定向转发机制定向转发意义 CG 节点的功能 节点的功能由节点支持的特性和功能决定。所有节点都能够发送和接收网格消息。节点还可以选择支持一个或多个附加功能,如 Configuration …...
在 Spring Boot 中使用 JSP
jsp? 好多年没用了。重新整一下 还费了点时间,记录一下。 项目结构: pom: <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://ww…...
如何配置一个sql server使得其它用户可以通过excel odbc获取数据
要让其他用户通过 Excel 使用 ODBC 连接到 SQL Server 获取数据,你需要完成以下配置步骤: ✅ 一、在 SQL Server 端配置(服务器设置) 1. 启用 TCP/IP 协议 打开 “SQL Server 配置管理器”。导航到:SQL Server 网络配…...
