SQLalchemy AttributeError:' str'对象没有属性' _sa_instance_state'

时间:2015-10-12 14:33:37

标签: python orm sqlalchemy

我尝试使用SQLAlchemy + Python向我的数据库添加项目,但一直收到错误。

我的database_setup.py:

class company(Base):
    __tablename__ = 'company'
    compID = Column(Integer, primary_key = True)
    name = Column(String(80), nullable = False)

class item(Base):
    __tablename__ = 'items'
    itemID = Column(Integer, primary_key = True)
    name = Column(String(80), nullable = False)
    category = Column(String(250))
    description = Column(String(250))
    price = Column(String(8))
    compID = Column(Integer, ForeignKey('company.compID'))
    company = relationship(company)

将sqlalchemy导入终端后,我定义了一个要插入的项目:

JawboneUP3 = item(
    itemID="1",
    name="Jawbone UP3",
    description="The latest UP!", 
    category="tracker",
    price="$174.99",
    company="Jawbone"
)

并绘制一个会话以添加和提交:

session.add(JawboneUP3)
session.commit()

当我提交时,我不断收到此错误:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.7/dist-packages/sqlalchemy/orm/session.py", line 1399, in add
    self._save_or_update_state(state)
  File "/usr/lib/python2.7/dist-packages/sqlalchemy/orm/session.py", line 1417, in _save_or_update_state
    halt_on=self._contains_state):
  File "/usr/lib/python2.7/dist-packages/sqlalchemy/orm/mapper.py", line 2037, in cascade_iterator
    parent_dict, visited_states, halt_on))
  File "/usr/lib/python2.7/dist-packages/sqlalchemy/orm/properties.py", line 932, in cascade_iterator
    get_all_pending(state, dict_)
  File "/usr/lib/python2.7/dist-packages/sqlalchemy/orm/attributes.py", line 761, in get_all_pending
   ret = [(instance_state(current), current)]
AttributeError: 'str' object has no attribute '_sa_instance_state'

我添加了一个&#39; Jawbone&#39;反对我的公司表,我了解我的&#39; JawboneUP3&#39;应该回到。通过我通过我的webserver脚本启用的浏览器表单正确添加了此对象。我相信我应该可以直接从终端添加项目。

3 个答案:

答案 0 :(得分:21)

我认为问题在于您如何定义相关的公司架构:

JawboneUP3 = item(itemID = "1", name = "Jawbone UP3", description = "The latest UP!", 
                  category = "tracker", price = "$174.99", company = "Jawbone")
                                                           # HERE^

item构造函数需要company实例,但您传递的是字符串值。解决它:

JawboneUP3 = item(itemID="1", 
                  name="Jawbone UP3", 
                  description="The latest UP!", 
                  category="tracker", 
                  price="$174.99", 
                  company=company(name="Jawbone"))

答案 1 :(得分:2)

首先,在Python中定义类时,最好使用大写字母来启动名称,如下所示:

class Company(Base):
    __tablename__ = 'company'
    compID = Column(Integer, primary_key = True)
    name = Column(String(80), nullable = False)

class Item(Base):
    __tablename__ = 'items'
    itemID = Column(Integer, primary_key = True)
    name = Column(String(80), nullable = False)
    category = Column(String(250))
    description = Column(String(250))
    price = Column(String(8))
    compID = Column(Integer, ForeignKey('company.compID'))
    company = relationship(company)

话虽如此,但这并不是您的代码抛出错误的原因。 :)

原因

Item构造函数需要将对象Company的实例作为变量company的值传递

解决方案1:数据库中不存在 Jawbone 公司

这里@alecxe的答案是有效的。

您应该用以下代码替换您的代码:

JawboneUP3 = Item(itemID="1", 
                  name="Jawbone UP3", 
                  description="The latest UP!", 
                  category="tracker", 
                  price="$174.99", 
                  company=company(name="Jawbone"))

将此对象添加到会话并命名更改实际上会为您的数据库创建两个条目:

  • 项目条目,名称为&#34; Jawbone UP3&#34;
  • 公司数据库中的一行,名称为&#34; Jawbone&#34;
  • 的公司

解决方案2: Jawbone 公司存在于您的数据库中

在这里你应该从你的桌子&#34;公司&#34;中取出公司 Jawbone 。并将其作为参数传递给Item构造函数,如下所示:

jawbone = session.query(Company).filter_by(name="Jawbone").first()

JawboneUP3 = Item(itemID="1", 
                  name="Jawbone UP3", 
                  description="The latest UP!", 
                  category="tracker", 
                  price="$174.99", 
                  company=jawbone)

session部分检查this

答案 2 :(得分:0)

from flask import Flask
from flask import request,redirect,render_template
from flask_sqlalchemy import SQLAlchemy

app=Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///students1.sqlite3'
db=SQLAlchemy(app)

class Categ(db.Model):
    id=db.Column(db.Integer,primary_key=True)
    name=db.Column(db.String(100))
    product=db.relationship('Product',backref='owner',lazy=True)

class Product(db.Model):
    id=db.Column(db.Integer,primary_key=True)
    pname=db.Column(db.String(100))
    price=db.Column(db.Integer)
    categ_id=db.Column(db.Integer,db.ForeignKey('categ.id'))

@app.route('/')
def home():
    return 'home'

@app.route('/post',methods=['POST','GET'])
def Productform():
    ob=Categ.query.all()
    if request.method=='POST':
        owner=request.form['ca']
        user = Categ.query.filter_by(name=owner).first()

        user=Product(pname=request.form['pname'],price=request.form['price'],owner=user)
        db.session.add(user)
        db.session.commit()

        return 'submit'

    return render_template('product.html',ob=ob)



@app.route('/categ',methods=['POST','GET'])
def Categoryform():
    if request.method=='POST':
        user=Categ(name=request.form['cname'])
        db.session.add(user)
        db.session.commit()

        return 'submit'

    return render_template('categ.html')


if __name__ == '__main__':
   app.run(debug=True)
   db.create_all()