Skip to content
Advertisement

Flask-SQLAlchemy Error – AttributeError: ‘NoneType’ object has no attribute ‘append’

Below I have defined SQLAlchemy models for a table containing companies and a table containing contracts. Each company can have many contracts while each contract can belong to one company (one to many relationship). This relationship is modelled by contracts = db.relationship('ContractModel', backref=db.backref('company', lazy=True)).

Models:

   class CompanyModel(db.Model):
       id = db.Column(db.Integer, primary_key=True)
       name = db.Column(db.String(64), unique=True, nullable=False)
       industry = db.Column(db.String(64), nullable=False)
       password = db.Column(db.String(64), nullable=False)
       company_logo_path = db.Column(db.String(255), unique=True, nullable=False)

       contracts = db.relationship('ContractModel', backref=db.backref('company', lazy=True))
   
   class ContractModel(db.Model):
       id = db.Column(db.Integer, primary_key=True) 
       length = db.Column(db.Integer, nullable=False)
       value = db.Column(db.Float, nullable=False)
       description = db.Column(db.Text, nullable=False)
       location = db.Column(db.String(50), nullable=False)
       date = db.Column(db.Date, nullable=False)
       company_name = db.Column(db.String, db.ForeignKey(CompanyModel.name), nullable=False)
       status = db.Column(db.Boolean, default=True, nullable=False)

I try to append a company to a contract (which links them) after creating a contract:

    contract = ContractModel(length=args['contract_length'], value=args['contract_value'], 
                                description=args['contract_description'], location=args['contract_location'], 
                                status=args['contract_status'], date=datetime.utcnow(), company_name=args['company_name'])
    
    associated_company = CompanyModel.query.filter_by(name=args['company_name']).first() # Company name resides in args['company_name']. This company has already been added to the database.
    contract.company.append(associated_company)

This gives the error: AttributeError: 'NoneType' object has no attribute 'append' where the culprit line is: contract.company.append(associated_company). Why am I not able to append a company to a contract even though their one to many relationship is defined? Did I model the relationship incorrectly?

Advertisement

Answer

Your relationship is correct. The only problem is that contract.company is currently an undefined attribute of your newly-created ContractModel object. You are then trying to append another object to this ‘NoneType’. The correct way to specify which company with which to link a contract would be by modifying the contract.company attribute instead of adding to it. You could even do this in two lines if you define associated_company before creating a new contract:

associated_company = CompanyModel.query.filter_by(name=args['company_name']).first()

contract = ContractModel(length=args['contract_length'], value=args['contract_value'], 
                                description=args['contract_description'], location=args['contract_location'], 
                                status=args['contract_status'], date=datetime.utcnow(), company_name=args['company_name'], 
                                company=associated_company)
User contributions licensed under: CC BY-SA
10 People found this is helpful
Advertisement