与SQL Alschemy的烧瓶关系-没有此类表格错误

时间:2020-08-17 17:57:21

标签: python flask sqlalchemy

我正在研究烧瓶关系教程。我正在尝试建立一个数据库,用于存储小狗,有关其玩具的信息以及有关其所有者的信息, basic.py:

# basic.py
import os
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate 

basedir = os.path.abspath(os.path.dirname(__file__))

app = Flask(__name__)

app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///'+os.path.join(basedir, 'data.sqlite')
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

db = SQLAlchemy(app)
Migrate(app, db)

class Puppy(db.Model):
     
    __tablename__ = 'puppies'
    
    id = db.Column(db.Integer, primary_key = True)
    name = db.Column(db.Text)
    toys = db.relationship('Toy', backref = 'puppy', lazy = 'dynamic')
    owner = db.relationship('Owner', backref = 'puppy', uselist = False)
    
    def __init__(self, name):
        self.name = name
        
    def __repr__(self):
        if self.owner:
            return "Puppy name is {self.name} and owner is {self.owner}"
        else:
            return "Puppy is {self.name} and has no owner yet"
        
    def report_toys(self):
        print("Here are my toys:")
        for toy in self.toys:
            print(toy.item_name)
    
class Toy(db.Model):
    
    __tablename__ = 'toys'
    
    id = db.Column(db.Integer, primary_key = True)
    item_name = db.Column(db.Text)
    puppy_id = db.Column(db.Integer, db.ForeignKey('puppies.id'))
    
    def __init__(self, item_name, puppy_id):
        self.item_name = item_name
        self.puppy_id = puppy_id
        
class Owner(db.Model):
    __tablename__ = 'owners'
    
    id = db.Column(db.Integer, primary_key = True)
    name = db.Column(db.Text)
    puppy_id = db.Column(db.Integer, db.ForeignKey('puppies.id'))
    
    def __init__(self, name, puppy_id):
        self.name = name
        self.puppy_id = puppy_id

然后我在models.py中建立一个手动数据库:

# models.py
from basic import db, Puppy, Owner, Toy

rufus = Puppy('Rufus')

fido = Puppy('Fido')

db.session.add_all([rufus, fido])
db.session.commit

rufus = Puppy.query.filter_by(name = 'Rufus').first()

kate = Owner('Kate', rufus.id)

toy1 = Toy('Chew Toy', rufus.id)
toy2 = Toy('Ball', rufus.id)

db.session.add_all([kate, toy1, toy2])
db.session.commit()

但是我遇到一个错误:

cursor.execute(statement, parameters)
sqlalchemy.exc.OperationalError: (raised as a result of Query-invoked autoflush; consider using a session.no_autoflush block if this flush is occurring prematurely)
(sqlite3.OperationalError) no such table: puppies
[SQL: INSERT INTO puppies (name) VALUES (?)]
[parameters: ('Rufus',)]
(Background on this error at: http://sqlalche.me/e/13/e3q8)

我是新来的,因此不胜感激。

3 个答案:

答案 0 :(得分:2)

您创建数据库了吗?

您需要导入db对象和模型,然后创建数据库,如下所示:

(venv) $ flask shell
>>> from basic import db
>>> from basic import Puppy, Toy, Owner
>>> db.create_all()

让我知道这是否可以解决您的问题

答案 1 :(得分:2)

错误消息显示数据库中没有幼犬表。要将迁移应用于数据库,在使用flask-migrate时需要一些步骤。

该链接会很有帮助https://flask-migrate.readthedocs.io/en/latest/

答案 2 :(得分:0)

由于使用的是flask_migrate,因此需要打开一个终端,请确保位于项目的同一工作目录中并运行以下命令:

您需要先运行它,然后再运行实际的Flask应用程序

    在环境文件夹中的
  1. CMD:
export class HeroFormComponent implements OnInit {
  @ViewChild("heroForm", null) heroForm: NgForm;
queryParams={};
  constructor(private route: ActivatedRoute) {}

  ngOnInit() {
    
    this.queryParams = { fname: "aaa", lname: "bbb" };
  }
}

通常,如果您不使用flask_migrate,而仅使用flask_sqlalchemy或SQLAlchemy vanilla,则应运行此程序。

    在环境文件夹中的
  1. CMD:
>>> set FLASK_APP= app.py (optional)
>>> flask db init
>>> flask db migrate -m 'Any name you want'  ---> what's inside the '' is the name of migrati
>>> flask db upgrade  (perform the actual migration)

编辑

每次您都从实例的数据库表中添加(或删除)某些东西

>>> from app import db
>>> db.create_all()
>>> exit() #or ctrl + z then enter 

成为--->

class Puppy(db.Model):
     
    __tablename__ = 'puppies'
    
    id = db.Column(db.Integer, primary_key = True)
    name = db.Column(db.Text)
    toys = db.relationship('Toy', backref = 'puppy', lazy = 'dynamic')
    owner = db.relationship('Owner', backref = 'puppy', uselist = False)

然后,您应该删除数据库文件(在您的情况下为“ data.sqlite”)(在工作目录中),然后再次运行上述代码,

实际上,通过运行上面的代码,您不仅可以创建数据库表,还可以创建实际的sqlite文件

相关问题