Pandas生成SQLite库与Django Model不兼容的问题排查
问题描述
我用Pandas生成SQLite3数据库,表结构看起来符合预期,但用对应Django Model访问时出问题,Django读不了这个数据库。
操作流程
- 先通过
views.py生成了output.txt,内容如下:
Interface Status Protocol Description BE9 down down BE9.1 down down BE9.100 down down Lo0 up up Lo8 up up Lo30 up up Lo100 up up ***MERGE LOOPBACK 100**** Lo111 up up Configured by NETCONF Lo200 up up ***MERGE LOOPBACK 200**** Gi0/0/0/0 down down Gi0/0/0/1 down down Gi0/0/0/2 admin-down admin-down Gi0/0/0/3 admin-down admin-down Gi0/0/0/4 admin-down admin-down Gi0/0/0/5 admin-down admin-down Gi0/0/0/6 admin-down admin-down
- 用以下代码把数据导入SQLite:
# Converting txt to DataFrame df = pd.read_fwf("output.txt") # debugging df df["Description"] = (df.iloc[:, 3:].fillna("").astype(str).apply(" ".join, axis=1).str.strip()) df = df.iloc[:, :4] # Converting to SQLITE3 database. If doesn't exist, a new one will be created connection = sqlite3.connect("db.sqlite3") # Inserting data into SQLITE database df.to_sql( name = "Devices_App_interfaces", # this is the name format given by Django for table names. con = connection, if_exists = "replace", index = False) connection.commit() connection.close() # End Process
- 在
models.py里定义了对应Model:
class Interfaces(models.Model): Interface = models.CharField(max_length=50) Status = models.CharField(max_length=50) Protocol = models.CharField(max_length=50) Description = models.CharField(max_length=50) def __str__(self): return self.name
执行makemigrations和migrate没报错,但调用Model数据没响应,添加到admin后报错:OperationalError at /admin/Devices_App/interfaces/,提示no such column: Devices_App_interfaces.id。
想问哪里操作错了?怎么正确加载外部数据库并在HTML展示?
解决方法
1. 核心问题:缺少Django默认主键字段id
Django的Model默认会自动添加自增主键字段id,但你用Pandas导入数据时生成的表没有这个字段,导致Django访问时找不到对应列报错。
两种修复方式
方式一:导入数据时手动添加
id列
在Pandas代码中,给DataFrame插入自增的id列后再导入数据库:# 在df = df.iloc[:, :4]之后添加 df.insert(0, 'id', range(1, len(df)+1))再执行
df.to_sql操作,生成的表就会带id主键列。方式二:修改Model指定现有字段为主键
如果你的Interface字段是唯一值,可以直接把它设为主键,省去添加id列的步骤:class Interfaces(models.Model): Interface = models.CharField(max_length=50, primary_key=True) Status = models.CharField(max_length=50) Protocol = models.CharField(max_length=50) Description = models.CharField(max_length=50) def __str__(self): return self.Interface # 原代码的self.name是错误的,改成对应字段名修改后重新执行
makemigrations和migrate,确保表结构与Model匹配。
2. 其他需要修正的细节
- Model的
__str__方法里原代码用了self.name,但你的Model里没有name字段,必须改成存在的字段(比如self.Interface),否则调用时会触发属性错误。 - 建议先让Django生成表结构再导入数据:先执行
makemigrations和migrate创建表,再把Pandas代码里的if_exists="replace"改成if_exists="append",避免覆盖Django生成的带主键的表结构。
3. 在HTML展示数据的步骤
- 编写视图函数(views.py):
from django.shortcuts import render from .models import Interfaces def interface_list(request): interfaces = Interfaces.objects.all() return render(request, 'interface_list.html', {'interfaces': interfaces})
- 创建HTML模板(templates/interface_list.html):
<!DOCTYPE html> <html> <head> <title>接口列表</title> </head> <body> <h1>网络接口信息</h1> <table border="1"> <tr> <th>接口名称</th> <th>状态</th> <th>协议状态</th> <th>描述</th> </tr> {% for interface in interfaces %} <tr> <td>{{ interface.Interface }}</td> <td>{{ interface.Status }}</td> <td>{{ interface.Protocol }}</td> <td>{{ interface.Description }}</td> </tr> {% endfor %} </table> </body> </html>
- 配置路由(urls.py):
from django.urls import path from .views import interface_list urlpatterns = [ path('interfaces/', interface_list, name='interface_list'), ]
内容的提问来源于stack exchange,提问作者Martin Barbieri
相关产品推荐
相关产品推荐

