Django对接Scrapy生成的SQLite库报错不存在noticia_tb.id如何解决?
问题解决方法
你遇到的错误是Django ORM的默认规则导致的:如果Model中没有显式指定主键字段,Django会自动给模型添加一个名为id的自增整数主键。你在模型的Meta里设置了managed = False,Django不会主动修改数据库表结构,而你用Scrapy建表时没有定义id字段,所以Django查询数据时默认请求id字段就会抛出找不到列的错误。
方案1:添加ID主键字段(推荐,符合Django开发规范)
修改Scrapy管道的建表和插入逻辑,给表加自增ID字段:
修改后Scrapy管道代码:
class ApinoticiaPipeline(object): def __init__(self): self.create_connection() self.create_table() def create_connection(self): self.conn = sqlite3.connect("myapinoticia.db") self.curr = self.conn.cursor() def create_table(self): self.curr.execute("""DROP TABLE IF EXISTS noticia_tb""") # 建表时新增id自增主键字段 self.conn.execute("""create table noticia_tb( id INTEGER PRIMARY KEY AUTOINCREMENT, title text, subtitulo text, url text, data text, image_url text )""") def process_item(self, item, spider): self.store_db(item) return item def store_db(self, item): # 插入时指定字段列表,跳过id让其自增,不需要修改传参逻辑 self.curr.execute("""insert into noticia_tb (title, subtitulo, url, data, image_url) values (?,?,?,?,?)""",(str(item['title'][0]),str(item['subtitulo'][0]),str(item['url'][0]),str(item['data'][0]),str(item['image_url'][0]))) self.conn.commit()
修改后重新运行Scrapy生成新的数据库即可,Django侧不需要做任何修改。
方案2:不添加ID字段正常运行
你可以在Django模型中显式指定现有字段中的唯一字段作为主键,Django就不会自动生成id字段了。比如新闻的url字段一般是全局唯一的,修改models.py如下:
修改后models.py代码:
class NoticiaTb(models.Model): title = models.TextField(blank=True, null=True) subtitulo = models.TextField(blank=True, null=True) # 给url字段加primary_key=True声明为主键 url = models.TextField(blank=True, null=True, primary_key=True) data = models.TextField(blank=True, null=True) image_url = models.TextField(blank=True, null=True) class Meta: managed = False db_table = 'noticia_tb'
注意:该方案要求你选为主键的字段不能有重复值、也不能有空值,否则会出现数据插入、查询异常。如果没有合适的唯一字段,还是建议使用方案1。
内容的提问来源于stack exchange,提问作者Myag
相关产品推荐
相关产品推荐

