SQLalchemy AttributeError: object 'str' does not have attribute '_sa_instance_state'

I'm trying to add an item to my database using SQLAlchemy + Python, but keep getting an error.

My 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 into my terminal, I define the item to insert:

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

and draw a session to add and commit:

 session.add(JawboneUP3) session.commit() 

When I send a message, 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 added the "Jawbone" object to my company table, and I understand that my "JawboneUP3" should be back. This object was added correctly through the browser form, which I included through my web server script. I believe that I should be able to add elements directly from the terminal.

+14
python orm sqlalchemy
source share
3 answers

I think the problem is how you define a companyโ€™s related scheme:

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

The item constructor expects an instance of company , but you are passing a string value. Fix it:

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

First of all, when defining a class in Python, it is useful to start capitalized names as follows:

 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) 

This is not why your code is causing an error. :)

Cause

The Item constructor expects an instance of the Company object to be passed as the value of the Company variable

Solution 1: Jawbone does not exist in your database

Here the @alecxe answer is valid.

You should replace your code with:

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

Adding this object to the session and making changes will actually result in two records in your database:

  • Record of an item named "Jawbone UP3"
  • A row in the company database, a company named "Jawbone"

Solution 2: Jawbone exists in your database

Here you should get the Jawbone company from your company table and pass it as an argument to the Item constructor, for example:

 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) 

For session parameter check this

+2
source share
 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() 
0
source share

All Articles