Python SQLalchemy AttributeError: 'str' 对象没有属性 '_sa_instance_state'
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/33083772/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
SQLalchemy AttributeError: 'str' object has no attribute '_sa_instance_state'
提问by mleafer
I'm trying to add an item to my database with SQLAlchemy + Python, but keep getting an error.
我正在尝试使用 SQLAlchemy + Python 向我的数据库中添加一个项目,但一直出现错误。
My database_setup.py:
我的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)
after importing sqlalchemy to my terminal, I define an item to insert:
将 sqlalchemy 导入到我的终端后,我定义了一个要插入的项目:
JawboneUP3 = item(
itemID="1",
name="Jawbone UP3",
description="The latest UP!",
category="tracker",
price="4.99",
company="Jawbone"
)
and draw a session to add and commit:
并绘制一个会话来添加和提交:
session.add(JawboneUP3)
session.commit()
When I submit, I keep getting this error:
当我提交时,我不断收到此错误:
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'
I have added a 'Jawbone' object to my company table, that I understand my 'JawboneUP3' should relate back to. This object was added correctly through a browser form that I enabled via my webserver script. I believe I should be able to add items right from the terminal though.
我在我的公司表中添加了一个“Jawbone”对象,我知道我的“JawboneUP3”应该与之相关。这个对象是通过我通过我的网络服务器脚本启用的浏览器表单正确添加的。我相信我应该能够直接从终端添加项目。
采纳答案by alecxe
I think the problem is in how you are defining the related company schema:
我认为问题在于您如何定义相关的公司架构:
JawboneUP3 = item(itemID = "1", name = "Jawbone UP3", description = "The latest UP!",
category = "tracker", price = "4.99", company = "Jawbone")
# HERE^
The item
constructor expects a company
instance but you are passing a string value. Fix it:
该item
构造函数需要一个company
实例,但你传递一个字符串值。修理它:
JawboneUP3 = item(itemID="1",
name="Jawbone UP3",
description="The latest UP!",
category="tracker",
price="4.99",
company=company(name="Jawbone"))
回答by Tiwtiw
First of all, when defining a class in Python, it is of good practice to to start the names with an uppercase letter like this:
首先,在 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)
That being said, it is not why your code throws an error. :)
话虽如此,这不是您的代码抛出错误的原因。:)
The reason
原因
The Item
constructor expects an instance of the object Company
to by passed as a value of the variable company
该Item
构造期望对象的一个实例Company
被作为变量的值来传递company
Solution 1: The Jawbonecompany does not exist in your database
解决方案 1:您的数据库中不存在Jawbone公司
Here the answer of @alecxe is valid.
这里@alecxe 的答案是有效的。
You should replace your code with:
您应该将代码替换为:
JawboneUP3 = Item(itemID="1",
name="Jawbone UP3",
description="The latest UP!",
category="tracker",
price="4.99",
company=company(name="Jawbone"))
Adding this object to the session and comiting the changes will actually make two entries to your database:
将此对象添加到会话并提交更改实际上会在您的数据库中创建两个条目:
- The item entry, with name "Jawbone UP3"
- A row in the companydatabase, a company with name "Jawbone"
- 项目条目,名称为“Jawbone UP3”
- 公司数据库中的一行,名为“Jawbone”的公司
Solution 2: The Jawbonecompany exists in your database
解决方案 2:Jawbone公司存在于您的数据库中
Here you should fetch the company Jawbonefrom your table "company" and pass it as an argument to the Item
constructor, like this:
在这里,您应该从表“company”中获取公司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="4.99",
company=jawbone)
For the session
part check this
对于session
部分检查这个
回答by Fauzan khan
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()