How to use marshmallow-sqlalchemy with async code? - sqlalchemy

I'm trying to use marshmallow-sqlalchemy with aiohttp and I have followed their docs with the basic example and I'm getting an error.
I have this schema:
from marshmallow_sqlalchemy import SQLAlchemyAutoSchema
from db.customer import Customer
class CustomerSchema(SQLAlchemyAutoSchema):
class Meta:
model = Customer
include_relationships = True
load_instance = True
And then the following code for the query:
from sqlalchemy import select
from db import db_conn
from db.customer import Customer
from queries.schema import CustomerSchema
customer_schema = CustomerSchema()
async def get_all_users():
async with db_conn.get_async_sa_session() as session:
statement = select(Customer)
results = await session.execute(statement)
_ = (results.scalars().all())
print(_)
response = customer_schema.dump(_, many=True)
print(response)
For the first print statement I'm getting
[<db.customer.Customer object at 0x10a183340>, <db.customer.Customer object at 0x10a183940>, <db.customer.Customer object at 0x10b0cd9d0>]
But then it fails with
File "/Users/ruslan/.local/share/virtualenvs/cft-RKlbQ9iX/lib/python3.9/site-packages/sqlalchemy/util/_concurrency_py3k.py", line 60, in await_only
raise exc.MissingGreenlet(
sqlalchemy.exc.MissingGreenlet: greenlet_spawn has not been called; can't call await_() here. Was IO attempted in an unexpected place? (Background on this error at: http://sqlalche.me/e/14/xd2s)
So how can I use marshmallow-sqlalchemy to serialize the SqlAlchemy reponse?
Another options (packages, etc) or a generic custom solutions are OK too.
For the time being I'm using this:
statement = select(Customer)
results = await session.execute(statement)
_ = (results.scalars().all())
response = {}
for result in _:
value = {k: (v if not isinstance(v, sqlalchemy.orm.state.InstanceState) else '_') for k, v in result.__dict__.items()}
response[f'customer {value["id"]}'] = value
return response
Full traceback:
Traceback (most recent call last):
File "/Users/ruslan/.local/share/virtualenvs/cft-RKlbQ9iX/lib/python3.9/site-packages/aiohttp/web_protocol.py", line 422, in _handle_request
resp = await self._request_handler(request)
File "/Users/ruslan/.local/share/virtualenvs/cft-RKlbQ9iX/lib/python3.9/site-packages/aiohttp/web_app.py", line 499, in _handle
resp = await handler(request)
File "/Users/ruslan/.local/share/virtualenvs/cft-RKlbQ9iX/lib/python3.9/site-packages/aiohttp/web_urldispatcher.py", line 948, in _iter
resp = await method()
File "/Users/ruslan/OneDrive/Home/Dev/projects/code/education/other/cft/views/user.py", line 24, in get
await get_all_users()
File "/Users/ruslan/OneDrive/Home/Dev/projects/code/education/other/cft/queries/user.py", line 18, in get_all_users
response = customer_schema.dump(_, many=True)
File "/Users/ruslan/.local/share/virtualenvs/cft-RKlbQ9iX/lib/python3.9/site-packages/marshmallow/schema.py", line 547, in dump
result = self._serialize(processed_obj, many=many)
File "/Users/ruslan/.local/share/virtualenvs/cft-RKlbQ9iX/lib/python3.9/site-packages/marshmallow/schema.py", line 509, in _serialize
return [
File "/Users/ruslan/.local/share/virtualenvs/cft-RKlbQ9iX/lib/python3.9/site-packages/marshmallow/schema.py", line 510, in <listcomp>
self._serialize(d, many=False)
File "/Users/ruslan/.local/share/virtualenvs/cft-RKlbQ9iX/lib/python3.9/site-packages/marshmallow/schema.py", line 515, in _serialize
value = field_obj.serialize(attr_name, obj, accessor=self.get_attribute)
File "/Users/ruslan/.local/share/virtualenvs/cft-RKlbQ9iX/lib/python3.9/site-packages/marshmallow/fields.py", line 310, in serialize
value = self.get_value(obj, attr, accessor=accessor)
File "/Users/ruslan/.local/share/virtualenvs/cft-RKlbQ9iX/lib/python3.9/site-packages/marshmallow_sqlalchemy/fields.py", line 27, in get_value
return super(fields.List, self).get_value(obj, attr, accessor=accessor)
File "/Users/ruslan/.local/share/virtualenvs/cft-RKlbQ9iX/lib/python3.9/site-packages/marshmallow/fields.py", line 239, in get_value
return accessor_func(obj, check_key, default)
File "/Users/ruslan/.local/share/virtualenvs/cft-RKlbQ9iX/lib/python3.9/site-packages/marshmallow/schema.py", line 472, in get_attribute
return get_value(obj, attr, default)
File "/Users/ruslan/.local/share/virtualenvs/cft-RKlbQ9iX/lib/python3.9/site-packages/marshmallow/utils.py", line 239, in get_value
return _get_value_for_key(obj, key, default)
File "/Users/ruslan/.local/share/virtualenvs/cft-RKlbQ9iX/lib/python3.9/site-packages/marshmallow/utils.py", line 253, in _get_value_for_key
return getattr(obj, key, default)
File "/Users/ruslan/.local/share/virtualenvs/cft-RKlbQ9iX/lib/python3.9/site-packages/sqlalchemy/orm/attributes.py", line 480, in __get__
return self.impl.get(state, dict_)
File "/Users/ruslan/.local/share/virtualenvs/cft-RKlbQ9iX/lib/python3.9/site-packages/sqlalchemy/orm/attributes.py", line 931, in get
value = self.callable_(state, passive)
File "/Users/ruslan/.local/share/virtualenvs/cft-RKlbQ9iX/lib/python3.9/site-packages/sqlalchemy/orm/strategies.py", line 879, in _load_for_state
return self._emit_lazyload(
File "/Users/ruslan/.local/share/virtualenvs/cft-RKlbQ9iX/lib/python3.9/site-packages/sqlalchemy/orm/strategies.py", line 1036, in _emit_lazyload
result = session.execute(
File "/Users/ruslan/.local/share/virtualenvs/cft-RKlbQ9iX/lib/python3.9/site-packages/sqlalchemy/orm/session.py", line 1689, in execute
result = conn._execute_20(statement, params or {}, execution_options)
File "/Users/ruslan/.local/share/virtualenvs/cft-RKlbQ9iX/lib/python3.9/site-packages/sqlalchemy/engine/base.py", line 1582, in _execute_20
return meth(self, args_10style, kwargs_10style, execution_options)
File "/Users/ruslan/.local/share/virtualenvs/cft-RKlbQ9iX/lib/python3.9/site-packages/sqlalchemy/sql/lambdas.py", line 481, in _execute_on_connection
return connection._execute_clauseelement(
File "/Users/ruslan/.local/share/virtualenvs/cft-RKlbQ9iX/lib/python3.9/site-packages/sqlalchemy/engine/base.py", line 1451, in _execute_clauseelement
ret = self._execute_context(
File "/Users/ruslan/.local/share/virtualenvs/cft-RKlbQ9iX/lib/python3.9/site-packages/sqlalchemy/engine/base.py", line 1813, in _execute_context
self._handle_dbapi_exception(
File "/Users/ruslan/.local/share/virtualenvs/cft-RKlbQ9iX/lib/python3.9/site-packages/sqlalchemy/engine/base.py", line 1998, in _handle_dbapi_exception
util.raise_(exc_info[1], with_traceback=exc_info[2])
File "/Users/ruslan/.local/share/virtualenvs/cft-RKlbQ9iX/lib/python3.9/site-packages/sqlalchemy/util/compat.py", line 207, in raise_
raise exception
File "/Users/ruslan/.local/share/virtualenvs/cft-RKlbQ9iX/lib/python3.9/site-packages/sqlalchemy/engine/base.py", line 1770, in _execute_context
self.dialect.do_execute(
File "/Users/ruslan/.local/share/virtualenvs/cft-RKlbQ9iX/lib/python3.9/site-packages/sqlalchemy/engine/default.py", line 717, in do_execute
cursor.execute(statement, parameters)
File "/Users/ruslan/.local/share/virtualenvs/cft-RKlbQ9iX/lib/python3.9/site-packages/sqlalchemy/dialects/postgresql/asyncpg.py", line 449, in execute
self._adapt_connection.await_(
File "/Users/ruslan/.local/share/virtualenvs/cft-RKlbQ9iX/lib/python3.9/site-packages/sqlalchemy/util/_concurrency_py3k.py", line 60, in await_only
raise exc.MissingGreenlet(
sqlalchemy.exc.MissingGreenlet: greenlet_spawn has not been called; can't call await_() here. Was IO attempted in an unexpected place? (Background on this error at: http://sqlalche.me/e/14/xd2s)

The problem in this case is that the Marshmallow schema is configured to load related models (include_relationships=True). Since the initial query doesn't load them automatically, the schema triggers a query to fetch them, and this causes the error.
The simplest solution, demonstrated in the docs, is to eagerly load the related objects with their "parent":
async def get_all_users():
async with db_conn.get_async_sa_session() as session:
# Let's assume a Customer has a 1 to many relationship with an Order model
statement = select(Customer).options(orm.selectinload(Customer.orders))
results = await session.execute(statement)
_ = (results.scalars().all())
print(_)
response = customer_schema.dump(_, many=True)
print(response)
There is more discussion in the Preventing Implicit IO when Using AsyncSession section of the docs.

Related

sqlalchemy Object with OrderingList - Session.commit() method fails

Model that has attribute in type of sqlalchemy OrderingList fails on Database Session Commit step (as Database I am using PostgreSQL 13):
from sqlalchemy import Column, Integer, String
from sqlalchemy.orm import relationship
from database.base_class import Base
from sqlalchemy.ext.orderinglist import ordering_list
class ContentType(Enum):
SCENE_HEADING = 'scene_heading'
ACTION = 'action'
CHARACTER = 'character'
PARENTHETICAL = 'parenthetical'
DIALOGUE = 'dialogue'
SHOT = 'shot'
TRANSITION = 'transition'
TEXT = 'text'
class EditorElement(Base):
"""
Class that represents the Table of Editor Elements.
"""
id = Column(Integer, primary_key=True, autoincrement=True, index=True)
content = Column(String, nullable=True)
content_type = Column(ContentType, nullable=True)
screenplay_id = Column(Integer, ForeignKey('screenplays.id', ondelete="CASCADE"), nullable=False)
screenplay = relationship("Screenplay", back_populates="elements")
class Screenplay(Base):
"""
Class that represents the screenplay table in the database.
"""
id = Column(Integer, primary_key=True, autoincrement=True, index=True)
name = Column(String, index=True, nullable=False)
elements = relationship("EditorElement", back_populates="screenplay", order_by="EditorElement.content_type",
collection_class=ordering_list('content_type'))
I am using FastAPI framework and in the CRUD file where the Screenplay is created, I have the following class:
class CRUDScreenplay(CRUDBase[models.Screenplay, schemas.ScreenplayBase, schemas.ScreenplayBase]):
#staticmethod
def create(db: Session, *, obj_in: schemas.ScreenplayCreate) -> models.Screenplay:
db_obj = models.Screenplay()
db_obj.name = obj_in['name']
for element in obj_in.get('elements'):
e = models.EditorElement(
content=element.content,
content_type=element.content_type,
screenplay_id=db_obj.id
)
db_obj.elements.append(e)
db.add(db_obj)
db.commit()
db.refresh(db_obj)
return db_obj
Using the PyCharm debugger I was able to check when the error occurs, it seems to appear after Session.commit(). Here is the object elements before the commit() method
And here is the elements object after the commit() method.
And the error in the console:
INFO: 127.0.0.1:52649 - "POST /api/v1/screenplays/ HTTP/1.1" 500 Internal Server Error
ERROR: Exception in ASGI application
Traceback (most recent call last):
File "C:\Users\userh\Playground\screenplay-writer\backend\.venv\lib\site-packages\sqlalchemy\sql\sqltypes.py", line 1649, in _object_value_for_elem
return self._object_lookup[elem]
KeyError: 'scene_heading'
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "C:\Users\userh\Playground\screenplay-writer\backend\.venv\lib\site-packages\uvicorn\protocols\http\httptools_impl.py", line 372, in run_asgi
result = await app(self.scope, self.receive, self.send)
File "C:\Users\userh\Playground\screenplay-writer\backend\.venv\lib\site-packages\uvicorn\middleware\proxy_headers.py", line 75, in __call__
return await self.app(scope, receive, send)
File "C:\Users\userh\Playground\screenplay-writer\backend\.venv\lib\site-packages\fastapi\applications.py", line 261, in __call__
await super().__call__(scope, receive, send)
File "C:\Users\userh\Playground\screenplay-writer\backend\.venv\lib\site-packages\starlette\applications.py", line 112, in __call__
await self.middleware_stack(scope, receive, send)
File "C:\Users\userh\Playground\screenplay-writer\backend\.venv\lib\site-packages\starlette\middleware\errors.py", line 181, in __call__
raise exc
File "C:\Users\userh\Playground\screenplay-writer\backend\.venv\lib\site-packages\starlette\middleware\errors.py", line 159, in __call__
await self.app(scope, receive, _send)
File "C:\Users\userh\Playground\screenplay-writer\backend\.venv\lib\site-packages\starlette\middleware\cors.py", line 84, in __call__
await self.app(scope, receive, send)
File "C:\Users\userh\Playground\screenplay-writer\backend\.venv\lib\site-packages\starlette\exceptions.py", line 82, in __call__
raise exc
File "C:\Users\userh\Playground\screenplay-writer\backend\.venv\lib\site-packages\starlette\exceptions.py", line 71, in __call__
await self.app(scope, receive, sender)
File "C:\Users\userh\Playground\screenplay-writer\backend\.venv\lib\site-packages\fastapi\middleware\asyncexitstack.py", line 21, in __call__
raise e
File "C:\Users\userh\Playground\screenplay-writer\backend\.venv\lib\site-packages\fastapi\middleware\asyncexitstack.py", line 18, in __call__
await self.app(scope, receive, send)
File "C:\Users\userh\Playground\screenplay-writer\backend\.venv\lib\site-packages\starlette\routing.py", line 656, in __call__
await route.handle(scope, receive, send)
File "C:\Users\userh\Playground\screenplay-writer\backend\.venv\lib\site-packages\starlette\routing.py", line 259, in handle
await self.app(scope, receive, send)
File "C:\Users\userh\Playground\screenplay-writer\backend\.venv\lib\site-packages\starlette\routing.py", line 61, in app
response = await func(request)
File "C:\Users\userh\Playground\screenplay-writer\backend\.venv\lib\site-packages\fastapi\routing.py", line 235, in app
response_data = await serialize_response(
File "C:\Users\userh\Playground\screenplay-writer\backend\.venv\lib\site-packages\fastapi\routing.py", line 130, in serialize_response
value, errors_ = await run_in_threadpool(
File "C:\Users\userh\Playground\screenplay-writer\backend\.venv\lib\site-packages\starlette\concurrency.py", line 39, in run_in_threadpool
return await anyio.to_thread.run_sync(func, *args)
File "C:\Users\userh\Playground\screenplay-writer\backend\.venv\lib\site-packages\anyio\to_thread.py", line 28, in run_sync
return await get_asynclib().run_sync_in_worker_thread(func, *args, cancellable=cancellable,
File "C:\Users\userh\Playground\screenplay-writer\backend\.venv\lib\site-packages\anyio\_backends\_asyncio.py", line 818, in run_sync_in_worker_thread
return await future
File "C:\Users\userh\Playground\screenplay-writer\backend\.venv\lib\site-packages\anyio\_backends\_asyncio.py", line 754, in run
result = context.run(func, *args)
File "pydantic\fields.py", line 854, in pydantic.fields.ModelField.validate
File "pydantic\fields.py", line 1071, in pydantic.fields.ModelField._validate_singleton
File "pydantic\fields.py", line 1118, in pydantic.fields.ModelField._apply_validators
File "pydantic\class_validators.py", line 313, in pydantic.class_validators._generic_validator_basic.lambda12
File "pydantic\main.py", line 678, in pydantic.main.BaseModel.validate
File "pydantic\main.py", line 562, in pydantic.main.BaseModel.from_orm
File "pydantic\main.py", line 1001, in pydantic.main.validate_model
File "pydantic\utils.py", line 409, in pydantic.utils.GetterDict.get
File "C:\Users\userh\Playground\screenplay-writer\backend\.venv\lib\site-packages\sqlalchemy\orm\attributes.py", line 481, in __get__
return self.impl.get(state, dict_)
File "C:\Users\userh\Playground\screenplay-writer\backend\.venv\lib\site-packages\sqlalchemy\orm\attributes.py", line 941, in get
value = self._fire_loader_callables(state, key, passive)
File "C:\Users\userh\Playground\screenplay-writer\backend\.venv\lib\site-packages\sqlalchemy\orm\attributes.py", line 977, in _fire_loader_callables
return self.callable_(state, passive)
File "C:\Users\userh\Playground\screenplay-writer\backend\.venv\lib\site-packages\sqlalchemy\orm\strategies.py", line 911, in _load_for_state
return self._emit_lazyload(
File "C:\Users\userh\Playground\screenplay-writer\backend\.venv\lib\site-packages\sqlalchemy\orm\strategies.py", line 1051, in _emit_lazyload
result = result.unique().scalars().all()
File "C:\Users\userh\Playground\screenplay-writer\backend\.venv\lib\site-packages\sqlalchemy\engine\result.py", line 1371, in all
return self._allrows()
File "C:\Users\userh\Playground\screenplay-writer\backend\.venv\lib\site-packages\sqlalchemy\engine\result.py", line 401, in _allrows
rows = self._fetchall_impl()
File "C:\Users\userh\Playground\screenplay-writer\backend\.venv\lib\site-packages\sqlalchemy\engine\result.py", line 1284, in _fetchall_impl
return self._real_result._fetchall_impl()
File "C:\Users\userh\Playground\screenplay-writer\backend\.venv\lib\site-packages\sqlalchemy\engine\result.py", line 1696, in _fetchall_impl
return list(self.iterator)
File "C:\Users\userh\Playground\screenplay-writer\backend\.venv\lib\site-packages\sqlalchemy\orm\loading.py", line 147, in chunks
fetch = cursor._raw_all_rows()
File "C:\Users\userh\Playground\screenplay-writer\backend\.venv\lib\site-packages\sqlalchemy\engine\result.py", line 393, in _raw_all_rows
return [make_row(row) for row in rows]
File "C:\Users\userh\Playground\screenplay-writer\backend\.venv\lib\site-packages\sqlalchemy\engine\result.py", line 393, in <listcomp>
return [make_row(row) for row in rows]
File "C:\Users\userh\Playground\screenplay-writer\backend\.venv\lib\site-packages\sqlalchemy\sql\sqltypes.py", line 1768, in process
value = self._object_value_for_elem(value)
File "C:\Users\userh\Playground\screenplay-writer\backend\.venv\lib\site-packages\sqlalchemy\sql\sqltypes.py", line 1651, in _object_value_for_elem
util.raise_(
File "C:\Users\userh\Playground\screenplay-writer\backend\.venv\lib\site-packages\sqlalchemy\util\compat.py", line 207, in raise_
raise exception
LookupError: 'scene_heading' is not among the defined enum values. Enum name: None. Possible values: None
However, the data was successfully created in the database, but FastAPI does not return anything due to this error.
There are some related issues in GitHub but I am was not able to figure out what is going on there:
Issue 1
Issue 2
Issue 3
Issue 4
UPDATE
Alembic (which is often used with FastAPI) or SLQAlchemy created the PostgreSQL ENUM Type in Uppercase.
I changed the definition of ContentType(enum.Enum) as it was in the example of the official documentation LINK. Thanks to #fchancel for pointing on that:
class ContentType(str, enum.Enum):
HEADING = 'HEADING'
ACTION = 'ACTION'
CHARACTER = 'CHARACTER'
PARENTHETICAL = 'PARENTHETICAL'
DIALOGUE = 'DIALOGUE'
SHOT = 'SHOT'
TRANSITION = 'TRANSITION'
TEXT = 'TEXT'
So, now my code works
It seems that when creating your elements, the content_type section is a problem, since it can't find heading_scene. To understand this, we need to see how you call your function and what obj_in contains.
However, it's possible that the source of the error is just your class ContentType(Enum) which to work properly should be class ContentType(str, Enum)

Dash Plotly error TypeError: Object of type DataFrame is not JSON serializable

Hello I am working with Dash for making dashboard.
Below is my code.
I tried to fix the error but not able to fix, Can anyone look into this?
on chrome i am getting. Error loading layout
I am getting TypeError
import dash_bootstrap_components as dbc
from dash import dcc
import dash_html_components as html
from dash import dash_table
import pandas as pd
import numpy as np
def getData():
return preprocess()
def back_to_df(dictio):
return pd.DataFrame.from_dict(dictio)
tblcols =[{"name": i, "id": i} for i in back_to_df(getData()).columns]
app = dash.Dash(__name__, external_stylesheets=[dbc.themes.BOOTSTRAP])
body = html.Div([
html.H1("Live rates")
, dbc.Row([
dbc.Col(html.Div([dcc.Interval('graph-update', interval = 80, n_intervals = 0),
dash_table.DataTable(
id = 'table',
data = getData(),
columns=tblcols,
page_size= 10,
style_table={'overflowX': 'auto'},
)]),width=3)
])
])
app.layout = html.Div([body])
#app.callback(
dash.dependencies.Output('table','data'),
[dash.dependencies.Input('graph-update', 'n_intervals')])
def updateTable(n):
return getData()
if __name__ == "__main__":
app.run_server(debug = False, port = 8010)
I tried to fix the error but not able to fix, Can anyone look into this?
I am getting error as follows.
Looking for help for below error. dash pandas plotly dataframe
Traceback (most recent call last):
File "C:\Users\Admin\anaconda3\lib\site-packages\flask\app.py", line 2447, in wsgi_app
response = self.full_dispatch_request()
File "C:\Users\Admin\anaconda3\lib\site-packages\flask\app.py", line 1952, in full_dispatch_request
rv = self.handle_user_exception(e)
File "C:\Users\Admin\anaconda3\lib\site-packages\flask\app.py", line 1821, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "C:\Users\Admin\anaconda3\lib\site-packages\flask\_compat.py", line 39, in reraise
raise value
File "C:\Users\Admin\anaconda3\lib\site-packages\flask\app.py", line 1950, in full_dispatch_request
rv = self.dispatch_request()
File "C:\Users\Admin\anaconda3\lib\site-packages\flask\app.py", line 1936, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "C:\Users\Admin\anaconda3\lib\site-packages\dash\dash.py", line 569, in serve_layout
to_json(layout),
File "C:\Users\Admin\anaconda3\lib\site-packages\dash\_utils.py", line 20, in to_json
return to_json_plotly(value)
File "C:\Users\Admin\anaconda3\lib\site-packages\plotly\io\_json.py", line 124, in to_json_plotly
return json.dumps(plotly_object, cls=PlotlyJSONEncoder, **opts)
File "C:\Users\Admin\anaconda3\lib\json\__init__.py", line 234, in dumps
return cls(
File "C:\Users\Admin\anaconda3\lib\site-packages\_plotly_utils\utils.py", line 59, in encode
encoded_o = super(PlotlyJSONEncoder, self).encode(o)
File "C:\Users\Admin\anaconda3\lib\json\encoder.py", line 199, in encode
chunks = self.iterencode(o, _one_shot=True)
File "C:\Users\Admin\anaconda3\lib\json\encoder.py", line 257, in iterencode
return _iterencode(o, 0)
File "C:\Users\Admin\anaconda3\lib\site-packages\_plotly_utils\utils.py", line 136, in default
return _json.JSONEncoder.default(self, obj)
File "C:\Users\Admin\anaconda3\lib\json\encoder.py", line 179, in default
raise TypeError(f'Object of type {o.__class__.__name__} '
TypeError: Object of type DataFrame is not JSON serializable```
Sounds like the getData function is returning a pandas DataFrame directly. That won't work. You'll need to do this:
return df.to_dict(orient='records')
That should work.

ProgrammingError - sqlalchemy - on_conflict_do_update

Following this question:
As Ilja Everilä mentioned in his answer, I created a table object:
from sqlalchemy import *
metadata = MetaData()
idTagTable = Table('id_tag', metadata,
Column('id', String(255), primary_key = True),
Column('category', String(20), nullable = False),
Column('createddate', Date, nullable = False),
Column('updatedon', Date, nullable = False)
)
After creating a table object, I changed insert and update statements:
insert_statement = sqlalchemy.dialects.postgresql.insert(idTagTable)
upsert_statement = insert_statement.on_conflict_do_update(
constraint=PrimaryKeyConstraint('id'),
set_={"updatedon": insert_statement.excluded.updateon,
"category":insert_statement.excluded.category}
)
insert_values = df.to_dict(orient='records')
conn.execute(upsert_statement, insert_values)
Now I am getting Programming Error:
Traceback (most recent call last):
File "<ipython-input-66-0fc6a1bf9c6b>", line 7, in <module>
conn.execute(upsert_statement, insert_values)
File "/home/ubuntu/anaconda2/lib/python2.7/site-packages/sqlalchemy/engine/base.py", line 945, in execute
return meth(self, multiparams, params)
File "/home/ubuntu/anaconda2/lib/python2.7/site-packages/sqlalchemy/sql/elements.py", line 263, in _execute_on_connection
return connection._execute_clauseelement(self, multiparams, params)
File "/home/ubuntu/anaconda2/lib/python2.7/site-packages/sqlalchemy/engine/base.py", line 1053, in _execute_clauseelement
compiled_sql, distilled_params
File "/home/ubuntu/anaconda2/lib/python2.7/site-packages/sqlalchemy/engine/base.py", line 1189, in _execute_context
context)
File "/home/ubuntu/anaconda2/lib/python2.7/site-packages/sqlalchemy/engine/base.py", line 1402, in _handle_dbapi_exception
exc_info
File "/home/ubuntu/anaconda2/lib/python2.7/site-packages/sqlalchemy/util/compat.py", line 203, in raise_from_cause
reraise(type(exception), exception, tb=exc_tb, cause=cause)
File "/home/ubuntu/anaconda2/lib/python2.7/site-packages/sqlalchemy/engine/base.py", line 1159, in _execute_context
context)
File "/home/ubuntu/anaconda2/lib/python2.7/site-packages/sqlalchemy/engine/default.py", line 467, in do_executemany
cursor.executemany(statement, parameters)
ProgrammingError: (psycopg2.ProgrammingError) syntax error at or near
")"
LINE 1: ...category) VALUES ('sports') ON CONFLICT () DO UPDAT...
^
Not Able to understand why I am getting this error.
The PrimaryKeyConstraint object you're using as constraint= argument is not bound to any table and would seem to produce nothing when rendered, as seen in ON CONFLICT (). Instead pass the primary key(s) of your table as the conflict_target and Postgresql will perform unique index inference:
upsert_statement = insert_statement.on_conflict_do_update(
constraint=idTagTable.primary_key,
set_={"updatedon": insert_statement.excluded.updateon,
"category":insert_statement.excluded.category}
)

Python 3.6: get JSON from aiohttp request

I have some application which uses aiohttp.
I sent POST request into approptiate endpoint, e.g.:
POST mysite.com/someendpoind/
with data similar to:
{"param1": "value1", "param2": "value2", ..., "paramn": None}
Then on backend side, I want to add some additional conditional into this request:
data = await request.json()
data["additional_conditional"] = True
But request.json() fails with an error:
[ERROR] Error handling request
Traceback (most recent call last):
File "/usr/local/lib/python3.5/dist-packages/aiohttp/web_protocol.py", line 422, in start
resp = yield from self._request_handler(request)
File "/usr/local/lib/python3.5/dist-packages/aiohttp/web.py", line 306, in _handle
resp = yield from handler(request)
File "/usr/local/lib/python3.5/dist-packages/aiohttp_session/__init__.py", line 129, in middleware
response = yield from handler(request)
File "/opt/bikeamp/auth/__init__.py", line 57, in wrapped
return (yield from f(request, user))
File "<my_module>.py", line 185, in <my_func>
data_json = await request.json()
File "/usr/local/lib/python3.5/dist-packages/aiohttp/web_request.py", line 469, in json
return loads(body)
File "/usr/lib/python3.5/json/__init__.py", line 319, in loads
return _default_decoder.decode(s)
File "/usr/lib/python3.5/json/decoder.py", line 339, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "/usr/lib/python3.5/json/decoder.py", line 357, in raw_decode
raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
Then I decided to check somehow what is the content of my request:
await request.read()
b'field1=value1&field2=value2&field3=value3&field4=&field5=&field6='
So, I'm not sure, but the problem may be with empty parameters.
Also, I was trying to get this data via:
data = await request.post()
data["additional_condition"] = True
But this returns MultiDictProxy. Python can't pickle these objects.
Is there any known solutions?
I had the same issue, if post was something like {"email": "some#email.com"} check it with:
#router('/', methods=['POST', ])
async def post_request(request):
post = await request.post()
email = post.get('email') # because it's MultiDict
logging.warning(post) # see post details
logging.warning(email) # shows value "some#email.com"
json = await request.text() #
logging.warning(json) # shows json if it was ajax post request

TypeError Object id is not JSON serializable

I have a Django view that is raising an error when the template tries to render:
TypeError: is not JSON serializable
(Where 76 is the id field)
Here is the view
def view2(request, model1object_id):
model1object = Model1.objects.get(pk=model1object_id)
# HERE
session_object = request.session.get('content')
if session_object:
del request.session['content']
request.session['content'] = model1object
context = {
"model1object": model1object,
....
}
return render(request, 'app/template2.html', context)
Here's my model for Model1:
class Model1(models.Model):
date_field = models.DateField()
another_field = models.CharField(max_length= 50, default="...")
def __str__(self):
return unicode(self.id) or u''
def get_absolute_url(self):
return reverse('app:model1', kwargs={'id': self.id})
EDIT: Traceback ->
Traceback (most recent call last):
File "/Library/Python/2.7/site-packages/django/core/handlers/base.py", line 235, in get_response
response = middleware_method(request, response)
File "/Library/Python/2.7/site-packages/django/contrib/sessions/middleware.py", line 50, in process_response
request.session.save()
File "/Library/Python/2.7/site-packages/django/contrib/sessions/backends/db.py", line 82, in save
obj = self.create_model_instance(data)
File "/Library/Python/2.7/site-packages/django/contrib/sessions/backends/db.py", line 68, in create_model_instance
session_data=self.encode(data),
File "/Library/Python/2.7/site-packages/django/contrib/sessions/backends/base.py", line 91, in encode
serialized = self.serializer().dumps(session_dict)
File "/Library/Python/2.7/site-packages/django/core/signing.py", line 95, in dumps
return json.dumps(obj, separators=(',', ':')).encode('latin-1')
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/__init__.py", line 250, in dumps
sort_keys=sort_keys, **kw).encode(obj)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/encoder.py", line 207, in encode
chunks = self.iterencode(o, _one_shot=True)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/encoder.py", line 270, in iterencode
return _iterencode(o, 0)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/encoder.py", line 184, in default
raise TypeError(repr(o) + " is not JSON serializable")
TypeError: <Model1: 76> is not JSON serializable
thanks
The error is because you are trying to save a model instance in the session, and the session middleware cannot serialize it to JSON.
request.session['content'] = model1object
It may be enough to store the id of the object instead of the object itself.
request.session['content_id'] = model1object.id
...
# retrieve from db later
model1object = Model1.objects.get(id=request.session['content_id'])
If you need to store more information in the session than the id, then you'll have to convert it to a format that is JSON serializable. For a simple model, it might be easiest to create a Python dict.
request.session['content'] = {
'id': model1object.id,
'name': model1object.name,
...
}
For more complicated models, you could look at the docs on serializing Django objects.