【问题标题】:InterfaceError in Python (Flask, SQLAlchemy) - Error binding parameter of a db.relationship parameterPython(Flask,SQLAlchemy)中的 InterfaceError - db.relationship 参数的错误绑定参数
【发布时间】:2020-09-20 20:53:19
【问题描述】:

我对 Flask 和 SQLAlchemy 非常陌生,但对 Python 有基本的了解。这也是我在这里的第一篇文章,我想我已经广泛寻找我的问题的答案。

我正在尝试创建一个非常简单的家谱数据库。我有两个表 - 一个个人表和一个家庭表(每个家庭都有一个可选的父亲和一个可选的母亲 - 每一个都是代表个人表中另一个人的外键)。

创建个人时必须使用姓氏和可选的前名和中间名。在个人表中还有一个与族表有关系的列。

当我尝试运行此代码时,我得到一个错误 -

sqlalchemy.exc.InterfaceError: (sqlite3.InterfaceError) 绑定参数 3 错误 - 可能是不受支持的类型。 [SQL: INSERT INTO individual (forename, middle_name, surname, family_id) VALUES (?, ?, ?, ?)] [参数:('David', None, 'Bloggs', )]

代码是:

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 Family(db.Model):

    __tablename__ = "family"

    id = db.Column(db.Integer,primary_key=True)
    mother_id = db.Column(db.Integer,db.ForeignKey("individual.id"))
    father_id = db.Column(db.Integer,db.ForeignKey("individual.id"))


    def __init__(self,mother_id='',father_id=''):
        self.mother_id = mother_id
        self.father_id = father_id


class Individual(db.Model):

    __tablename__ = "individual"

    id = db.Column(db.Integer, primary_key=True)
    forename = db.Column(db.Text)
    middle_name = db.Column(db.Text)
    surname = db.Column(db.Text)
    family_id = db.Column(db.Integer,db.ForeignKey("family.id"))

    def __init__(self,surname,forename=None,middle_name=None):
        self.forename = forename
        self.middle_name = middle_name
        self.surname = surname
        self.family_id = db.relationship("family",backref="individual",lazy="dynamic")

    def __repr__(self):
        return f"""The individual is {self.forename} {self.middle_name}
        {self.surname}, their father is {self.family.father_id.forename}
        {self.family.father_id.middle_name} {self.family.father_id.surname}
        and their mother is {self.family.mother_id.forename}
        {self.family.mother_id.middle_name} {self.family.mother_id.surname}"""

db.create_all()

person1 = Individual("Bloggs", "David")
person2 = Individual("Bloggs", "Robert")
person3 = Individual("Smith", "Mary", "Ann")

db.session.add_all([person1,person2,person3])
db.session.commit()

print(person1)
print(person2)
print(person3)

任何帮助表示赞赏。谢谢。

【问题讨论】:

    标签: python-3.x flask-sqlalchemy


    【解决方案1】:

    有必要谈谈你的数据库设计中的一点

    数据库需要家庭和个人之间的双重关系,因为创建个人需要一个家庭,在另一个地方,创建一个家庭需要一个母亲和父亲的身份。这是个问题。 一种设计方法是分配一个 familiy_id,每个人都有一个 family_id 和一个在家庭中的角色。

    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 Family(db.Model):
    
        __tablename__ = "family"
    
        id = db.Column(db.Integer,primary_key=True)
        family_id = db.Column(db.Integer, unique=True)
        family_name = db.Column(db.Text)
    
    
        def __init__(self,family_id, family_name):
            self.family_id = family_id
            self.family_name = family_name
    
    
    class Individual(db.Model):
    
        __tablename__ = "individual"
    
        id = db.Column(db.Integer, primary_key=True)
        forename = db.Column(db.Text)
        middle_name = db.Column(db.Text)
        surname = db.Column(db.Text)
        role = db.Column(
            db.Integer,
            nullable=False,
            server_default=db.text("'0'"),
            comment="Indicates whether is the role in the family . 2 = Father, 1= Mother, 0 = Other",
        )
        family_id = db.Column(db.Integer,db.ForeignKey("family.id"))
    
        def __init__(self, forename, middle_name, surname, family_id, role=0):
            self.forename = forename
            self.middle_name = middle_name
            self.surname = surname
            self.family_id = family_id
            self.role = role
    
       
    db.create_all()
    
    family = Family(1, "Kay Fam.")
    
    son = Individual("John", "David", "Kay", 1)
    father = Individual("Dave", "Luis", "Kay", 1, 2)
    
    db.session.add(family)
    db.session.add(son)
    db.session.add(father)
    
    db.session.commit()
    

    新案例: 将个人分配给多个家庭/角色需要修改

     class Individual(db.Model):
    
    
        __tablename__ = "individual"
    
        id = db.Column(db.Integer, primary_key=True)
        individual_id = db.Column(db.Integer)
        forename = db.Column(db.Text)
        middle_name = db.Column(db.Text)
        surname = db.Column(db.Text)
        role = db.Column(
            db.Integer,
            nullable=False,
            server_default=db.text("'0'"),
            comment="Indicates whether is the role in the family . 2 = Father, 1= Mother, 0 = Other",
        )
        family_id = db.Column(db.Integer,db.ForeignKey("family.id"))
    
        def __init__(self, individual_id,  forename, middle_name, surname, family_id, role=0):
            self.individual_id = individual_id
            self.forename = forename
            self.middle_name = middle_name
            self.surname = surname
            self.family_id = family_id
            self.role = role
    

    individual_id 很重要,为什么?因为不是唯一的,它是一个与个人相关的数字(id 表示 DB 上的位置,例如 individual_id == DNI) 这样就可以多次添加具有不同家庭/角色的个人。

    【讨论】:

    • 谢谢,这很有意义。然后我还有一个后续问题=一个人可以是一个家庭的孩子,一个或多个其他家庭的母亲/父亲——这是否意味着这个数据库设计需要以某种方式改变?您是否可能有一个单独的关系表,它将家庭 ID 与个人 ID 和角色类型联系起来?再次感谢您的宝贵时间,非常感谢。
    • 嗨,我根据您的问题编辑答案。问候
    • 非常感谢您的帮助和时间,非常感谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-24
    • 1970-01-01
    • 1970-01-01
    • 2016-02-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多