mbijou
mbijou

Reputation: 87

Can't include models in python-eve except in run py file

I have written an python-eve app using SQLAlchemy for my Models. Well it works perfectly when I define the Models in my run.py file. When I define my tables in another file and import them in run.py then the server runs but when I try to send a request via curl to one of those resources I get an error.

My curl request:

curl -i 127.0.0.1:5000/people

And i get following error:

o = self.data[key]()

KeyError: 'People'

Well I know that error from before! It appears when eve is trying to find something that is not existing. Eve doesn't find the Model People. I don't know why it can't find the People model.

I don't want to have all my models inside run.py. I want to have my tables separated in another files.

However if I implement the models in run.py it works all perfectly I can make GET, POST, PATCH, DELETE Request.

For some reason the Models must be defined in run.py and it must also be defined upside the app initialization.

Well here is my Code:

run.py


from sqlalchemy.ext.declarative import declarative_base
from eve import Eve
from eve_sqlalchemy import SQL
from eve_sqlalchemy.validation import ValidatorSQL
from tables import People

Base = declarative_base()

app = Eve(validator=ValidatorSQL, data=SQL)

# bind SQLAlchemy
db = app.data.driver
Base.metadata.bind = db.engine
db.Model = Base
db.create_all()

if __name__ == '__main__':
    app.run(debug=True, use_reloader=False)

settings.py


from eve_sqlalchemy.decorators import registerSchema
from eve.utils import config
from tables import People

registerSchema('people')(People)

DOMAIN = {
        'people': People._eve_schema['people'],
        }

RESOURCE_METHODS = ['GET', 'POST']

SQLALCHEMY_DATABASE_URI = 'postgresql://USER:PASSWORD@localhost:5432/SOMEDB'

ITEM_METHODS = ['GET', 'DELETE', 'PATCH', 'PUT']

DEBUG = True

ID_FIELD = 'id'

config.ID_FIELD = ID_FIELD

tables.py


from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import column_property
from sqlalchemy import Column, Integer, String, DateTime, func

Base = declarative_base()


class CommonColumns(Base):
    __abstract__ = True
    _created = Column(DateTime, default=func.now())
    _updated = Column(DateTime, default=func.now(), onupdate=func.now())
    _etag = Column(String(40))

class People(CommonColumns):
    __tablename__ = 'people'
    _id = Column(Integer, primary_key=True, autoincrement=True)
    firstname = Column(String(80))
    lastname = Column(String(120))
    fullname = column_property(firstname + " " + lastname)

    @classmethod
    def from_tuple(cls, data):
        """Helper method to populate the db"""
        return cls(firstname=data[0], lastname=data[1])

Upvotes: 1

Views: 170

Answers (1)

metmirr
metmirr

Reputation: 4302

The problem is usage of two different Base class. Remove the Base class which inside run.py and import Base class from tables.py to run.py

#run.py
from tables import Base, People   #import Base
Base = declarative_base()         #remove this line

If you use a new Base class then your tables wont be created because this new Base class doesn't have model class derived from. Metadata keeps tables attached with it.

Upvotes: 1

Related Questions