Reputation: 87
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
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