SQLAlchemy Falcon Class error
Я пытаюсь настроить API, используя Falcon и SQLAlchemy, используя базу данных postgresql. Использование gunicorn для запуска API
Я получаю следующую ошибку при попытке доступа к /v1/users.
Я пытался просмотреть документацию по SQLAlchemy, но не смог найти никакого работающего решения.
Спасибо
[2017-03-15 10:20:26 +0100] [20516] [ERROR] Error handling request /v1/users
Traceback (most recent call last):
File "/Users/juliencourtes/Documents/projects/FalconAPI/venv/lib/python3.6/site-packages/gunicorn/workers/sync.py", line 135, in handle
self.handle_request(listener, req, client, addr)
File "/Users/juliencourtes/Documents/projects/FalconAPI/venv/lib/python3.6/site-packages/gunicorn/workers/sync.py", line 176, in handle_request
respiter = self.wsgi(environ, resp.start_response)
File "/Users/juliencourtes/Documents/projects/FalconAPI/venv/lib/python3.6/site-packages/falcon/api.py", line 209, in __call__
responder(req, resp, **params)
File "/Users/juliencourtes/Documents/projects/FalconAPI/app/api/v1/users.py", line 50, in on_get
users = session.query(User).all()
File "/Users/juliencourtes/Documents/projects/FalconAPI/venv/lib/python3.6/site-packages/sqlalchemy/orm/scoping.py", line 157, in do
return getattr(self.registry(), name)(*args, **kwargs)
File "/Users/juliencourtes/Documents/projects/FalconAPI/venv/lib/python3.6/site-packages/sqlalchemy/orm/session.py", line 1330, in query
return self._query_cls(entities, self, **kwargs)
File "/Users/juliencourtes/Documents/projects/FalconAPI/venv/lib/python3.6/site-packages/sqlalchemy/orm/query.py", line 139, in __init__
self._set_entities(entities)
File "/Users/juliencourtes/Documents/projects/FalconAPI/venv/lib/python3.6/site-packages/sqlalchemy/orm/query.py", line 148, in _set_entities
entity_wrapper(self, ent)
File "/Users/juliencourtes/Documents/projects/FalconAPI/venv/lib/python3.6/site-packages/sqlalchemy/orm/query.py", line 3947, in __init__
"expected - got '%r'" % (column, )
sqlalchemy.exc.InvalidRequestError: SQL expression, column, or mapped entity expected - got '<function User at 0x1040216a8>'
Файлы моих проектов
main.py
import falcon
from app.api.v1 import users
from app.middleware import DatabaseSessionManager
from app.database import db_session, init_session
from app.api.common import base
class App(falcon.API):
def __init__(self,*args, **kwargs):
super(App, self).__init__(*args, **kwargs)
self.add_route('/',base.BaseResource())
self.add_route('/v1/users',users.Collection())
init_session()
mdlw = [DatabaseSessionManager(db_session)]
application = App(middleware=mdlw)
session.py
import sqlalchemy.orm.scoping as scoping
from sqlalchemy.exc import SQLAlchemyError
from app import config
class DatabaseSessionManager(object):
def __init__(self, db_session):
self._session_factory = db_session
self._scoped = isinstance(db_session, scoping.ScopedSession)
def process_request(self, req, res, resource=None):
req.context['session'] = self._session_factory
def process_response(self, req, res, resource=None):
session = req.context['session']
if config.DB_AUTOCOMMIT:
try:
session.commit()
except SQLAlchemyError as ex:
session.rollback()
if self._scoped:
session.remove()
else:
session.close()
база данных init.py
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker, scoped_session
import psycopg2
from app import config
db_session = scoped_session(sessionmaker())
engine = create_engine('postgresql+psycopg2://xxxxx@localhost/falcon_api')
def init_session():
db_session.configure(bind=engine)
user.py
from sqlalchemy import Column
from sqlalchemy import String, Integer,Text
from sqlalchemy.dialects.postgresql import UUID, JSONB
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
def User(Base):
__tablename__ = 'user'
id = Column('id', UUID, primary_key=True)
firstname = Column('firstname', String)
lastname = Column('lastname', String)
#It tells python how to print the class, used for debugging
def __repr__(self):
return "<User(id='%s', name='%s', lastname='%s')>"% \
(self.id, self.firstname, self.lastname)
def __init__(self, id , firstname, lastname):
self.id = id
self.firstname = firstname
self.lastname = lastname
апи /v1/users.py
import falcon
import json
from sqlalchemy.ext.declarative import declarative_base
try:
from collections import OrderedDict
except ImportError:
OrderedDict = dict
from app.models import User
class Collection():
"""
Handle for endpoint: /v1/users
"""
def to_json(self, body_dict):
return json.dumps(body_dict)
def on_error(self, resp, error=None):
resp.status = error['status']
meta = OrderedDict()
meta['code'] = error['code']
meta['message'] = error['message']
obj = OrderedDict()
obj['meta'] = meta
resp.body = self.to_json(obj)
def on_success(self, resp, data=None):
resp.status = falcon.HTTP_200
meta = OrderedDict()
meta['code'] = 200
meta['message'] = 'OK'
obj = OrderedDict()
obj['meta'] = meta
obj['data'] = data
resp.body = self.to_json(obj)
def on_get(self, req, resp):
session = req.context['session']
#Bugging here
users = session.query(User).all()
2 ответа
Я столкнулся с той же проблемой.. Это исправлено в моем случае для следующих изменений.. вместо session.remove() используйте следующий код.
if self._scoped:
self._session_factory.remove()
Это будет работать
Мы создаем модели для SQL в python, используя Class, который наследует встроенный класс от ORM, например SQLAlchemy. Вот вы пытаетесь создать
User
модель. Но поскольку для правильной работы это должен быть класс, вместо этого вы объявили его как функцию в .
Все, что вам нужно сделать, чтобы заставить его работать, это просто изменить
def User
к
class User
.
Так
user.py
будет выглядеть примерно так:
...
class User(Base):
__tablename__ = 'user'
...