SQLAlchemy: ValueError - sqlalchemy

I have these tables:
1) User
class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key = True)
fname = Column(String(45))
lname = Column(String(45))
mail = Column(String(45))
password = Column(String(45))
courses = relationship("Course", secondary=user_course, backref="users")
universities = relationship("University", secondary=user_university, backref="users")
def add_university(self, university):
universities = self.universities
universities.append(university)
self.universities = universities
def add_course(self, course):
courses = self.courses
courses.append(course)
self.courses = courses
2) University
class University(Base):
__tablename__ = 'universities'
id = Column(Integer, primary_key=True)
date = Column(DateTime)
name = Column(String(45))
3) Course
class Course(Event):
__tablename__ = 'courses'
id = Column(Integer, ForeignKey('events.id'), primary_key=True)
name = Column(String(45))
year = Column(Integer)
__mapper_args__ = {
'polymorphic_identity':'course',
}
events = relationship("Event", secondary=course_event, backref="courses")
So a many to many to many with user-course and user-university and a many to many with course-events (the parent of course).
When I try to add a university with my method defined in user it works but when i try to add a course i get this error:
Traceback (most recent call last):
File "/Users/arnoutaertgeerts/Documents/Eclips/SlideTalk 2.0/test_SQL.py", line 473, in <module>
arnout.add_course(Analyse)
File "/Users/arnoutaertgeerts/Documents/Eclips/SlideTalk 2.0/test_SQL.py", line 101, in add_course
courses.append(course)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/SQLAlchemy-0.7.9-py2.7.egg/sqlalchemy/orm/collections.py", line 1046, in append
item = __set(self, item, _sa_initiator)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/SQLAlchemy-0.7.9-py2.7.egg/sqlalchemy/orm/collections.py", line 1021, in __set
item = getattr(executor, 'fire_append_event')(item, _sa_initiator)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/SQLAlchemy-0.7.9-py2.7.egg/sqlalchemy/orm/collections.py", line 714, in fire_append_event
item, initiator)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/SQLAlchemy-0.7.9-py2.7.egg/sqlalchemy/orm/attributes.py", line 800, in fire_append_event
value = fn(state, value, initiator or self)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/SQLAlchemy-0.7.9-py2.7.egg/sqlalchemy/orm/attributes.py", line 1026, in emit_backref_from_collection_append_event
passive=PASSIVE_NO_FETCH)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/SQLAlchemy-0.7.9-py2.7.egg/sqlalchemy/orm/attributes.py", line 854, in append
collection.append_with_event(value, initiator)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/SQLAlchemy-0.7.9-py2.7.egg/sqlalchemy/orm/collections.py", line 655, in append_with_event
getattr(self._data(), '_sa_appender')(item, _sa_initiator=initiator)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/SQLAlchemy-0.7.9-py2.7.egg/sqlalchemy/orm/collections.py", line 1046, in append
item = __set(self, item, _sa_initiator)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/SQLAlchemy-0.7.9-py2.7.egg/sqlalchemy/orm/collections.py", line 1021, in __set
item = getattr(executor, 'fire_append_event')(item, _sa_initiator)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/SQLAlchemy-0.7.9-py2.7.egg/sqlalchemy/orm/collections.py", line 714, in fire_append_event
item, initiator)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/SQLAlchemy-0.7.9-py2.7.egg/sqlalchemy/orm/attributes.py", line 800, in fire_append_event
value = fn(state, value, initiator or self)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/SQLAlchemy-0.7.9-py2.7.egg/sqlalchemy/orm/attributes.py", line 1020, in emit_backref_from_collection_append_event
_acceptable_key_err(state, initiator)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/SQLAlchemy-0.7.9-py2.7.egg/sqlalchemy/orm/attributes.py", line 982, in _acceptable_key_err
manager_of_class(initiator.class_)[initiator.key]))
ValueError: Object not associated with attribute of type User.courses
However, If I stop letting course inherit from Event, it does work!
Any ideas?

Problem solved! Here is the ticket: http://sqlalchemy.org/trac/ticket/2674

Related

Django student here: I'm I getting a ValueError when creating a superuser using a custom made User class

I am working on a project that requires one to only create an account if their other details such as username are already in the database.
For this I created a custom user class named Account and linked the username field through a OneToOne relationship to the Reg No in the Student class.
I manually prepopulated the database with a single record so as to be able to create a superuser, because the creation of an account would require an existing Student record. But I am getting a value error on the terminal like so:
(djangoenv) myMachine:~/Django9/eschool$ python3 manage.py createsuperuser
Email: ********#**.me
Username (Student.School_ID): 1
Password:
Password (again):
Traceback (most recent call last):
File "/home/biketi21/Django9/eschool/manage.py", line 22, in <module>
main()
File "/home/biketi21/Django9/eschool/manage.py", line 18, in main
execute_from_command_line(sys.argv)
File "/home/biketi21/anaconda3/envs/djangoenv/lib/python3.9/site-packages/django/core/management/__init__.py", line 419, in execute_from_command_line
utility.execute()
File "/home/biketi21/anaconda3/envs/djangoenv/lib/python3.9/site-packages/django/core/management/__init__.py", line 413, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/home/biketi21/anaconda3/envs/djangoenv/lib/python3.9/site-packages/django/core/management/base.py", line 354, in run_from_argv
self.execute(*args, **cmd_options)
File "/home/biketi21/anaconda3/envs/djangoenv/lib/python3.9/site-packages/django/contrib/auth/management/commands/createsuperuser.py", line 79, in execute
return super().execute(*args, **options)
File "/home/biketi21/anaconda3/envs/djangoenv/lib/python3.9/site-packages/django/core/management/base.py", line 398, in execute
output = self.handle(*args, **options)
File "/home/biketi21/anaconda3/envs/djangoenv/lib/python3.9/site-packages/django/contrib/auth/management/commands/createsuperuser.py", line 157, in handle
validate_password(password2, self.UserModel(**fake_user_data))
File "/home/biketi21/anaconda3/envs/djangoenv/lib/python3.9/site-packages/django/db/models/base.py", line 485, in __init__
_setattr(self, field.name, rel_obj)
File "/home/biketi21/anaconda3/envs/djangoenv/lib/python3.9/site-packages/django/db/models/fields/related_descriptors.py", line 310, in __set__
super().__set__(instance, value)
File "/home/biketi21/anaconda3/envs/djangoenv/lib/python3.9/site-packages/django/db/models/fields/related_descriptors.py", line 215, in __set__
raise ValueError(
ValueError: Cannot assign "1": "Account.username" must be a "Student" instance.
Below is my Models.py:
I'm using MySQL Database as the backend.
from django.db import models
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager
# Create your models here.
class Student(models.Model):
FirstName = models.CharField(max_length=50)
Surname = models.CharField(max_length=50)
Reg_No = models.CharField(max_length=11, unique=True)
National_ID = models.IntegerField(unique=True)
School_ID = models.AutoField(primary_key=True)
County = models.CharField(max_length=20)
Sub_County = models.CharField(max_length=50)
Course_Title = models.ForeignKey("Course", on_delete=models.CASCADE)
Admission_Date = models.DateField(auto_now=True)
def __str__(self):
return str(self.Reg_No)
class Course(models.Model):
Course_Title = models.CharField(max_length=100)
Course_ID = models.CharField(max_length=10)
Number_of_Semesters = models.IntegerField()
Total_Cost_of_Course = models.IntegerField()
def __str__(self):
return str(self.Course_ID)
class MyAccountManager(BaseUserManager):
def create_user(self, email, username, password=None):
if not email:
raise ValueError('Users must have an email address.')
if not username:
raise ValueError('Users must have a username.')
user = self.model(
email=self.normalize_email(email),
username=username,
)
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self, email, username, password):
user = self.create_user(
email=self.normalize_email(email),
password=password,
username=username,
)
user.is_admin = True
user.is_staff = True
user.is_superuser = True
user.save(using=self._db)
return user
class Account(AbstractBaseUser):
email = models.EmailField(verbose_name='email', max_length=60, unique=True)
username = models.OneToOneField(Student, unique=True, on_delete=models.CASCADE)
date_joined = models.DateTimeField(verbose_name='date joined', auto_now_add=True)
last_login = models.DateTimeField(verbose_name='last login', auto_now=True)
is_admin = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
is_superuser = models.BooleanField(default=False)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['username']
objects = MyAccountManager()
def __str__(self):
return self.username
def has_perm(self, perm, obj=None):
return self.is_admin
def has_module_perms(self, app_label):
return True
Any help in solving this problem is appreciated.

SQLalchemy | fastAPI. Trying to add a new row in association table gives KeyError

So I have a fastAPI project that uses sqlalchemy to connect to a postgresql database.
I use alembic to build the database and have version control on it.
My issue is now that everything works quite like it should with the many to many relationship. All stocks show the portfolio they belong to, and all portfolios show the stocks they have in them (This was tested with manually entering the data in PGAdmin).
The issue now is that every time I try to add a new connection (add a stock to a portfolio) it throws me a "Key-Error".
Here is the models.py:
class PortfolioStock(Base):
__tablename__ = "portfolio_stocks"
id = Column(Integer, primary_key=True)
stock_id = Column(Integer, ForeignKey("stocks.id", ondelete="CASCADE"))
portfolio_id = Column(Integer, ForeignKey("portfolios.id", ondelete="CASCADE"))
count = Column(Integer, nullable=True)
buy_in = Column(Float, nullable=True)
stock = relationship("Stock", back_populates="portfolios")
portfolio = relationship("Portfolio", back_populates="stocks")
#a lot of these proxy associations here because of another bug I encountered
#basically every column in the two models associated here have a association proxy row.(couldn't find another fix)
stock_created_at = association_proxy(target_collection="stock", attr="created_at")
portfolio_name = association_proxy(target_collection="portfolio", attr="name")
def __init__(self, portfolio=None, stock=None, buy_in=None, count=None):
self.portfolio = portfolio
self.stock = stock
self.buy_in = buy_in
self.count = count
class Stock(Base):
__tablename__ = "stocks"
id = Column(Integer, primary_key=True, nullable=False)
...
status = Column(Integer, nullable=False, server_default="0")
portfolios = relationship("PortfolioStock", back_populates="stock")
class Portfolio(Base):
__tablename__ = "portfolios"
id = Column(Integer, primary_key=True, nullable=False)
name = Column(String, nullable=False)
user_id = Column(Integer, ForeignKey("users.id", ondelete="CASCADE"), nullable=False)
monetary_goal = Column(Float, nullable=True)
dividends_goal = Column(Float, nullable=True)
created_at = Column(TIMESTAMP(timezone=True), nullable=False, server_default=text("now()"))
stocks = relationship("PortfolioStock", back_populates="portfolio")
Here are some snippets to show what I do in the fastapi route.
First i get the portfolio in question and the stocks that are passed into the body.
I iterate over the stocks and grab the corresponding entry in the DB for each one.
And finally I try to just add these stocks to the list that contains all the models that are in the portfolio.
portfolio = db.query(models.Portfolio).filter(models.Portfolio.id == portfolio_id).first()
for stock in stock_ids:
stock = db.query(models.Stock).filter(models.Stock.id == stock_id).first()
portfolio.stocks.append(stock)
setattr(stock, "status", "1")
db.add(portfolio)
db.commit()
db.refresh(portfolio)
return portfolio
And here is the error message that I receive when I try to call this route from postman.
Traceback (most recent call last):
File "/home/maxi/dev/captstone_venv/lib/python3.8/site-packages/uvicorn/protocols/http/httptools_impl.py", line 375, in run_asgi
result = await app(self.scope, self.receive, self.send)
File "/home/maxi/dev/captstone_venv/lib/python3.8/site-packages/uvicorn/middleware/proxy_headers.py", line 75, in __call__
return await self.app(scope, receive, send)
File "/home/maxi/dev/captstone_venv/lib/python3.8/site-packages/fastapi/applications.py", line 259, in __call__
await super().__call__(scope, receive, send)
File "/home/maxi/dev/captstone_venv/lib/python3.8/site-packages/starlette/applications.py", line 112, in __call__
await self.middleware_stack(scope, receive, send)
File "/home/maxi/dev/captstone_venv/lib/python3.8/site-packages/starlette/middleware/errors.py", line 181, in __call__
raise exc
File "/home/maxi/dev/captstone_venv/lib/python3.8/site-packages/starlette/middleware/errors.py", line 159, in __call__
await self.app(scope, receive, _send)
File "/home/maxi/dev/captstone_venv/lib/python3.8/site-packages/starlette/middleware/cors.py", line 84, in __call__
await self.app(scope, receive, send)
File "/home/maxi/dev/captstone_venv/lib/python3.8/site-packages/starlette/exceptions.py", line 82, in __call__
raise exc
File "/home/maxi/dev/captstone_venv/lib/python3.8/site-packages/starlette/exceptions.py", line 71, in __call__
await self.app(scope, receive, sender)
File "/home/maxi/dev/captstone_venv/lib/python3.8/site-packages/fastapi/middleware/asyncexitstack.py", line 21, in __call__
raise e
File "/home/maxi/dev/captstone_venv/lib/python3.8/site-packages/fastapi/middleware/asyncexitstack.py", line 18, in __call__
await self.app(scope, receive, send)
File "/home/maxi/dev/captstone_venv/lib/python3.8/site-packages/starlette/routing.py", line 656, in __call__
await route.handle(scope, receive, send)
File "/home/maxi/dev/captstone_venv/lib/python3.8/site-packages/starlette/routing.py", line 259, in handle
await self.app(scope, receive, send)
File "/home/maxi/dev/captstone_venv/lib/python3.8/site-packages/starlette/routing.py", line 61, in app
response = await func(request)
File "/home/maxi/dev/captstone_venv/lib/python3.8/site-packages/fastapi/routing.py", line 222, in app
raw_response = await run_endpoint_function(dependant=dependant, values=values, is_coroutine=is_coroutine)
File "/home/maxi/dev/captstone_venv/lib/python3.8/site-packages/fastapi/routing.py", line 159, in run_endpoint_function
return await run_in_threadpool(dependant.call, **values)
File "/home/maxi/dev/captstone_venv/lib/python3.8/site-packages/starlette/concurrency.py", line 39, in run_in_threadpool
return await anyio.to_thread.run_sync(func, *args)
File "/home/maxi/dev/captstone_venv/lib/python3.8/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 "/home/maxi/dev/captstone_venv/lib/python3.8/site-packages/anyio/_backends/_asyncio.py", line 818, in run_sync_in_worker_thread
return await future
File "/home/maxi/dev/captstone_venv/lib/python3.8/site-packages/anyio/_backends/_asyncio.py", line 754, in run
result = context.run(func, *args)
File "/home/maxi/dev/./api/routers/stock.py", line 151, in add_stock_to_portfolio
portfolio.stocks.append(stock)
File "/home/maxi/dev/captstone_venv/lib/python3.8/site-packages/sqlalchemy/orm/collections.py", line 1169, in append
item = __set(self, item, _sa_initiator)
File "/home/maxi/dev/captstone_venv/lib/python3.8/site-packages/sqlalchemy/orm/collections.py", line 1134, in __set
item = executor.fire_append_event(item, _sa_initiator)
File "/home/maxi/dev/captstone_venv/lib/python3.8/site-packages/sqlalchemy/orm/collections.py", line 753, in fire_append_event
return self.attr.fire_append_event(
File "/home/maxi/dev/captstone_venv/lib/python3.8/site-packages/sqlalchemy/orm/attributes.py", line 1330, in fire_append_event
value = fn(state, value, initiator or self._append_token)
File "/home/maxi/dev/captstone_venv/lib/python3.8/site-packages/sqlalchemy/orm/attributes.py", line 1632, in emit_backref_from_collection_append_event
child_impl = child_state.manager[key].impl
KeyError: 'portfolio'
I have already tried to rename all relationships to figure out where exactly the error is coming from.
And it seems to be that t he relationship of stock = relationship("Stock", back_populates="portfolios") is a culprit of the issue.
Looking in debugging mode it seems that the model I'm trying to access is not having the correct keys in it, so my guess is that I'm either making the new association wrong and it's not portfolio.stocks.append(stock) (which worked before I fixed another issue) or that the relationships are wrong / something is missing to make it work.
I would really greatly appreciate some suggestions.
If you need additional information please let me know.

Object of type 'User' is not JSON serializable (Parent class)

I'm trying to insert a record in my database through my Flask API. The relationship between the User and Project classes is One to Many (a User can have many projects). I'm having no problems at inserting a new User, but when I try to insert a new Project in the database, it actually works, but the User attributte in the Project cant't be be converted to JSON. Here is my code:
User Model file:
class Usuario(db.Model):
id = db.Column(db.BigInteger, primary_key=True)
login = db.Column(db.String(80), unique=True, nullable=False)
email = db.Column(db.String(120), unique=True, nullable=False)
nome = db.Column(db.String(80), nullable=False)
senha = db.Column(db.String(80), nullable=False)
telefone = db.Column(db.String(80))
receivedNotification = db.Column(
db.Boolean, default=False, nullable=False)
receivedEmail = db.Column(db.Boolean, default=False, nullable=False)
emailVerificated = db.Column(db.Boolean, default=False, nullable=False)
imagem = db.Column(db.LargeBinary(length=(2 ** 32) - 1))
def __init__(self, login='', email='', nome='', senha='',
telefone='', received_notification=False,
received_email=False, email_verificated=False, imagem=None, init_dict=None):
if init_dict is None:
self.login = login
self.email = email
self.nome = nome
self.senha = senha
self.telefone = telefone
self.receivedNotification = received_notification
self.receivedEmail = received_email
self.emailVerificated = email_verificated
self.imagem = imagem
else:
for key in init_dict:
setattr(self, key, init_dict[key])
class UsuarioSchema(ma.Schema):
class Meta:
fields = ('id', 'login', 'email', 'nome', 'telefone',
'receivedNotification', 'receivedEmail', 'emailVerificated', 'imagem')
user_schema = UsuarioSchema()
users_schema = UsuarioSchema(many=True)
Project Model file:
class Projeto(db.Model):
codigo = db.Column(db.BigInteger, primary_key=True)
nome = db.Column(db.String(100))
descricao = db.Column(db.String(200))
dataCriacao = db.Column(db.Date)
dataPrevFinalizacao = db.Column(db.Date)
dataFinalizacao = db.Column(db.Date)
usuarioAdmId = db.Column(db.BigInteger,
db.ForeignKey('usuario.id'), nullable=False)
usuarioAdm = db.relationship('Usuario',
backref=db.backref('projetos', lazy=True))
def __init__(self, nome, descricao, data_criacao,
data_prev_finalizacao, usuario_adm_id, data_finalizacao=None):
self.nome = nome
self.descricao = descricao
self.dataCriacao = data_criacao
self.dataPrevFinalizacao = data_prev_finalizacao
self.dataFinalizacao = data_finalizacao
self.usuarioAdmId = usuario_adm_id
class ProjetoSchema(ma.Schema):
class Meta:
fields = ('nome', 'descricao', 'dataCriacao',
'dataPrevFinalizacao', 'dataFinalizacao', 'usuarioAdm')
projeto_schema = ProjetoSchema()
projetos_schema = ProjetoSchema(many=True)
My route code to add a project:
#projeto_controller.route(mapping, methods=['POST'])
def add_projeto():
nome = request.json['nome']
descricao = request.json['descricao']
data_criacao = request.json['dataCriacao']
data_criacao = datetime.strptime(
data_criacao, '%b %d, %Y %I:%M:%S %p').date()
data_prev_finalizacao = request.json['dataPrevFinalizacao']
data_prev_finalizacao = datetime.strptime(
data_prev_finalizacao, '%b %d, %Y %I:%M:%S %p').date()
usuario_adm_id = request.json['usuarioAdm']['id']
usuario_adm = request.json['usuarioAdm']
usuario = mUsuario.Usuario.query.get(usuario_adm_id)
usuarioAdm = usuario
new_projeto = mProjeto.Projeto(nome=nome, descricao=descricao,
data_criacao=data_criacao,
data_prev_finalizacao=data_prev_finalizacao,
usuario_adm_id=usuario_adm_id)
new_projeto.usuarioAdm = usuarioAdm
usuarioAdm.projetos.append(new_projeto)
db.session.commit()
return mProjeto.projeto_schema.jsonify(new_projeto)
Error message:
File "/anaconda3/envs/KeepSoft/lib/python3.7/site-packages/flask/app.py", line 2309, in __call__
return self.wsgi_app(environ, start_response)
File "/anaconda3/envs/KeepSoft/lib/python3.7/site-packages/flask/app.py", line 2295, in wsgi_app
response = self.handle_exception(e)
File "/anaconda3/envs/KeepSoft/lib/python3.7/site-packages/flask/app.py", line 1741, in handle_exception
reraise(exc_type, exc_value, tb)
File "/anaconda3/envs/KeepSoft/lib/python3.7/site-packages/flask/_compat.py", line 35, in reraise
raise value
File "/anaconda3/envs/KeepSoft/lib/python3.7/site-packages/flask/app.py", line 2292, in wsgi_app
response = self.full_dispatch_request()
File "/anaconda3/envs/KeepSoft/lib/python3.7/site-packages/flask/app.py", line 1815, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/anaconda3/envs/KeepSoft/lib/python3.7/site-packages/flask/app.py", line 1718, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/anaconda3/envs/KeepSoft/lib/python3.7/site-packages/flask/_compat.py", line 35, in reraise
raise value
File "/anaconda3/envs/KeepSoft/lib/python3.7/site-packages/flask/app.py", line 1813, in full_dispatch_request
rv = self.dispatch_request()
File "/anaconda3/envs/KeepSoft/lib/python3.7/site-packages/flask/app.py", line 1799, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/Users/user/Python/KeepSoftPythonAPI/controller/ProjetoController.py", line 93, in add_projeto
return mProjeto.projeto_schema.jsonify(new_projeto)
File "/anaconda3/envs/KeepSoft/lib/python3.7/site-packages/flask_marshmallow/schema.py", line 42, in jsonify
return flask.jsonify(data, *args, **kwargs)
File "/anaconda3/envs/KeepSoft/lib/python3.7/site-packages/flask/json/__init__.py", line 321, in jsonify
dumps(data, indent=indent, separators=separators) + '\n',
File "/anaconda3/envs/KeepSoft/lib/python3.7/site-packages/flask/json/__init__.py", line 179, in dumps
rv = _json.dumps(obj, **kwargs)
File "/anaconda3/envs/KeepSoft/lib/python3.7/json/__init__.py", line 238, in dumps
**kw).encode(obj)
File "/anaconda3/envs/KeepSoft/lib/python3.7/json/encoder.py", line 201, in encode
chunks = list(chunks)
File "/anaconda3/envs/KeepSoft/lib/python3.7/json/encoder.py", line 431, in _iterencode
yield from _iterencode_dict(o, _current_indent_level)
File "/anaconda3/envs/KeepSoft/lib/python3.7/json/encoder.py", line 405, in _iterencode_dict
yield from chunks
File "/anaconda3/envs/KeepSoft/lib/python3.7/json/encoder.py", line 438, in _iterencode
o = _default(o)
File "/anaconda3/envs/KeepSoft/lib/python3.7/site-packages/flask/json/__init__.py", line 81, in default
return _json.JSONEncoder.default(self, o)
File "/anaconda3/envs/KeepSoft/lib/python3.7/json/encoder.py", line 179, in default
raise TypeError(f'Object of type {o.__class__.__name__} '
TypeError: Object of type Usuario is not JSON serializable
I expected the a Project JSON returned, so i can convert to the Project class that exists in my mobile application.
You should have a function that returns the objects of the Projeto class in a dictionary format, and then convert it into jsonify it. Something like
def get_objects(self):
"""
This function creates a dictionary and assigns
the keys of the dictionary with the objects of
the class and returns it in a json format.
"""
data = {
'nome': self.nome,
'descricao': self.descricao,
'data_criacao': self.dataCriacao,
'data_prev_finalizacao': self.dataPrevFinalizacao,
'data_finalizacao': self.dataFinalizacao,
'usuario_adm_id': self.usuarioAdmId
}
return jsonify(data)
If you need the data to be returned in a JSON format for a model, you'll need the data to be returned in a JSON format. Currently with this line of code,
return mProjeto.projeto_schema.jsonify(new_projeto)
what you're doing is that you are trying to convert a Usuario and Projeto object into a JSON object, which is not a valid data type the jsonify function supports. That is what is indicated by the message
raise TypeError(f'Object of type {o.__class__.__name__} '
TypeError: Object of type Usuario is not JSON serializable
The same can be done for the Usuario class as well.
After searching a lot, I was able to solve my problem. I had to define explicitly that the object usuario defined in the ProjetoSchema class was Nested object, so only them when retrieving a Projeto, this object would be properly loaded as a JSON.
So, now this the modified Schema:
class ProjetoSchema(ma.Schema):
class Meta:
fields = ('codigo', 'nome', 'descricao', 'dataCriacao',
'dataPrevFinalizacao', 'dataFinalizacao', 'usuarioAdm')
model = Projeto
usuarioAdm = ma.Nested('UsuarioSchema', exclude=('projetos',))
perfis = ma.Nested('PerfilSchema', many=True, exclude=('projeto',))
projeto_schema = ProjetoSchema()
projetos_schema = ProjetoSchema(many=True)
And this is the modified UsuarioSchema:
class UsuarioSchema(ma.Schema):
class Meta:
fields = ('id', 'login', 'email', 'nome', 'telefone', 'receivedNotification',
'receivedEmail', 'emailVerificated', 'imagem')
model = Usuario
projetos = ma.Nested('ProjetoSchema', many=True, exclude=('usuarioAdm',))
perfis = ma.Nested('PerfilSchema', many=True, exclude=('usuario',))
user_schema = UsuarioSchema()
users_schema = UsuarioSchema(many=True)
This way, I won't need to deal with infinite nested objects as I did before I got the final code. Some of these lines wasn't necessary after all, because when I retrive a Usuario, I omitted the field that would contain it's Projeto children and when retrive a Projeto, it properly shows it's parent now.
Forgive my English, I'm brazilian.
Thanks for all the tips and solutions.

Getting error from sqlalchemy

Here is the error log i get this error when i try to create a new user when i do:
u = User (...)
Error log:
Traceback (most recent call last)
File "/usr/lib/python3.6/site-packages/flask/app.py", line 1994, in __call__
return self.wsgi_app(environ, start_response)
File "/usr/lib/python3.6/site-packages/flask/app.py", line 1985, in wsgi_app
response = self.handle_exception(e)
File "/usr/lib/python3.6/site-packages/flask/app.py", line 1540, in handle_exception
reraise(exc_type, exc_value, tb)
File "/usr/lib/python3.6/site-packages/flask/_compat.py", line 33, in reraise
raise value
File "/usr/lib/python3.6/site-packages/flask/app.py", line 1982, in wsgi_app
response = self.full_dispatch_request()
File "/usr/lib/python3.6/site-packages/flask/app.py", line 1614, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/usr/lib/python3.6/site-packages/flask/app.py", line 1517, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/usr/lib/python3.6/site-packages/flask/_compat.py", line 33, in reraise
raise value
File "/usr/lib/python3.6/site-packages/flask/app.py", line 1612, in full_dispatch_request
rv = self.dispatch_request()
File "/usr/lib/python3.6/site-packages/flask/app.py", line 1598, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/home/quechon/PycharmProjects/untitled3/myapp/login/routes.py", line 66, in _register_process
timecreated=datetime.datetime.utcnow()
File "<string>", line 4, in __init__
File "/usr/lib/python3.6/site-packages/sqlalchemy/orm/state.py", line 414, in _initialize_instance
manager.dispatch.init_failure(self, args, kwargs)
File "/usr/lib/python3.6/site-packages/sqlalchemy/util/langhelpers.py", line 60, in __exit__
compat.reraise(exc_type, exc_value, exc_tb)
File "/usr/lib/python3.6/site-packages/sqlalchemy/util/compat.py", line 186, in reraise
raise value
File "/usr/lib/python3.6/site-packages/sqlalchemy/orm/state.py", line 411, in _initialize_instance
return manager.original_init(*mixed[1:], **kwargs)
File "/home/quechon/PycharmProjects/untitled3/myapp/models.py", line 80, in __init__
self.follow(self)
File "/home/quechon/PycharmProjects/untitled3/myapp/models.py", line 47, in follow
if not self.is_following(user):
File "/home/quechon/PycharmProjects/untitled3/myapp/models.py", line 57, in is_following
return self.followed.filter_by(followed_id=user.id).first() is not None
File "/usr/lib/python3.6/site-packages/sqlalchemy/orm/query.py", line 1517, in filter_by
return self.filter(sql.and_(*clauses))
File "<string>", line 2, in filter
File "/usr/lib/python3.6/site-packages/sqlalchemy/orm/base.py", line 198, in generate
self = args[0]._clone()
File "/usr/lib/python3.6/site-packages/sqlalchemy/orm/dynamic.py", line 278, in _clone
orm_util.instance_str(instance), self.attr.key))
sqlalchemy.orm.exc.DetachedInstanceError: Parent instance <User at 0x7fe2ac0e6e80> is not bound to a Session, and no contextual session is established; lazy load operation of attribute 'followed' cannot proceed
This is the model:
class User(db.Model):
__tablename__ = 'user'
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(100), unique=True)
email = db.Column(db.String(100))
password = db.Column(db.Binary)
profilepic = db.Column(db.String)
timecreated = db.Column(db.DateTime)
#picture = db.relationship('Picture', backref='owner', lazy='dynamic')
comment = db.relationship('Comment', backref='user', lazy='dynamic')
post = db.relationship('Post', backref='user', lazy='dynamic')
followed = db.relationship('Follow', foreign_keys=[Follow.follower_id],
backref=db.backref('follower', lazy='joined'),
lazy='dynamic',
cascade='all, delete-orphan')
followers = db.relationship('Follow',
foreign_keys=[Follow.followed_id],
backref=db.backref('followed', lazy='joined'),
lazy='dynamic',
cascade='all, delete-orphan')
def follow(self, user):
if not self.is_following(user):
f = Follow(follower=self, followed=user)
db.session.add(f)
def unfollow(self, user):
f = self.followed.filter_by(followed_id=user.id).first()
if f:
db.session.delete(f)
def is_following(self, user):
return self.followed.filter_by(followed_id=user.id).first() is not None
def is_followed_by(self, user):
return self.followers.filter_by(follower_id=user.id).first() is not None
#property
def followed_posts(self):
return Post.query.join(Follow.followed_id == Post.user_id)\
.filter(Follow.follower_id == self.id)
def is_authenticated(self):
return True
def is_active(self):
return True
def is_anonymous(self):
return False
def get_id(self):
return str(self.id)
def __init__(self, **kwargs):
self.follow(self)
def __repr__(self):
return f'<id - {self.id} | - {self.username}>'
I would like to know why that happened and how to avoid this error next time
The only thing i found online about was to use lazy='subquery' instead of lazy='dynamic' but using that wont allow my query to use filter_by attribute.
It looks like you are trying to interact with your flask app via the interactive shell. You can do this using the command line interface (CLI).
See docs:
http://flask.pocoo.org/docs/0.12/shell/

Issues in flask-restless due to sqlalchemy.db.Boolean

I have just moved from flask-sqlalchemy to just sqlalchemy. And I have started getting below issue.
Issue 1 :
I have two models
class Candidate(db.Model):
__tablename__ = 'candidate'
id = db.Column(db.Integer, primary_key=True)
country_id = db.Column(db.Integer, db.ForeignKey('country.id'), nullable=True)
first_name = db.Column(db.String(100), nullable=True)
last_name = db.Column(db.String(100))
email = db.Column(db.String(255), nullable=False, unique=True)
is_deleted = db.Column(db.Boolean, nullable=False, default=False, server_default=db.text("false"))
class Country(db.Model):
__tablename__ = 'country'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(150), nullable=False, unique=True)
created_on = db.Column(db.DateTime, default=_get_date_time)
modified_on = db.Column(db.TIMESTAMP, onupdate=_get_date_time, nullable=False, server_default=db.text("CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP"))
is_deleted = db.Column(db.Boolean, nullable=False, default=False, server_default=db.text("false"))
I created tables in my students db using alembic. The migration file it generated looks like
# ... snip ...
op.create_table('country',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('name', sa.String(length=150), nullable=False),
sa.Column('created_on', sa.DateTime(), nullable=True),
sa.Column('modified_on', sa.TIMESTAMP(), server_default=sa.text(u'CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'), nullable=False),
sa.Column('is_deleted', sa.Boolean(), server_default=sa.text(u'false'), nullable=False),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('name')
)
op.create_table('candidate',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('first_name', sa.String(length=100), nullable=True),
sa.Column('last_name', sa.String(length=100), nullable=True),
sa.Column('country_id', sa.Integer(), nullable=True),
sa.Column('email', sa.String(length=255), nullable=False),
sa.Column('is_deleted', sa.Boolean(), server_default=sa.text(u'false'), nullable=False),
sa.ForeignKeyConstraint(['country_id'], ['country.id'], ),
sa.UniqueConstraint('email'),
)
I loaded data from the mysqldump that I had created when I was using falsk-sqlalchemy.
INSERT INTO `country` VALUES (1,'India','2015-05-16 16:51:30','2015-05-16 11:21:30',0),(2,'Australia','2015-05-16 17:10:33','2015-05-16 11:40:33',0);
INSERT INTO `candidate` VALUES (1,1,'Jon','Snow','jon-snow#got.com',0);
Issue : But mysqldump should have put false in place of is_deleted, don't you think? Also note that when I manually replace 0 by false in mysqldump for is_deleted, I don't fall into Issue 2.
Issue 2 :
I use flask restless API layer to do CRUD operations.
# ... snip ...
manager = flask.ext.restless.APIManager(app, session=mysession)
manager.create_api(Country, methods=['GET'])
manager.create_api(Candidate, methods=['GET','POST'])
# ... snip ...
Issue : When I hit /candidate api, I get below error. It was working fine with flask-sqlalchemy
ValueError: int_to_boolean only accepts None, 0 or 1
Traceback for Issue 2
Traceback (most recent call last):
File "/home/hussain/workspace/api/lib/python2.7/site-packages/flask/app.py", line 1836, in __call__
return self.wsgi_app(environ, start_response)
File "/home/hussain/workspace/api/lib/python2.7/site-packages/flask/app.py", line 1820, in wsgi_app
response = self.make_response(self.handle_exception(e))
File "/home/hussain/workspace/api/lib/python2.7/site-packages/flask_cors/extension.py", line 110, in wrapped_function
return cors_after_request(app.make_response(f(*args, **kwargs)))
File "/home/hussain/workspace/api/lib/python2.7/site-packages/flask_restful/__init__.py", line 270, in error_router
return original_handler(e)
File "/home/hussain/workspace/api/lib/python2.7/site-packages/flask_cors/extension.py", line 110, in wrapped_function
return cors_after_request(app.make_response(f(*args, **kwargs)))
File "/home/hussain/workspace/api/lib/python2.7/site-packages/flask/app.py", line 1403, in handle_exception
reraise(exc_type, exc_value, tb)
File "/home/hussain/workspace/api/lib/python2.7/site-packages/flask/app.py", line 1817, in wsgi_app
response = self.full_dispatch_request()
File "/home/hussain/workspace/api/lib/python2.7/site-packages/flask/app.py", line 1477, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/home/hussain/workspace/api/lib/python2.7/site-packages/flask_cors/extension.py", line 110, in wrapped_function
return cors_after_request(app.make_response(f(*args, **kwargs)))
File "/home/hussain/workspace/api/lib/python2.7/site-packages/flask_restful/__init__.py", line 270, in error_router
return original_handler(e)
File "/home/hussain/workspace/api/lib/python2.7/site-packages/flask_cors/extension.py", line 110, in wrapped_function
return cors_after_request(app.make_response(f(*args, **kwargs)))
File "/home/hussain/workspace/api/lib/python2.7/site-packages/flask/app.py", line 1381, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/home/hussain/workspace/api/lib/python2.7/site-packages/flask/app.py", line 1475, in full_dispatch_request
rv = self.dispatch_request()
File "/home/hussain/workspace/api/lib/python2.7/site-packages/flask/app.py", line 1461, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/home/hussain/workspace/api/lib/python2.7/site-packages/flask_restless/views.py", line 157, in decorator
return func(*args, **kw)
File "/home/hussain/workspace/api/lib/python2.7/site-packages/mimerender.py", line 229, in wrapper
result = target(*args, **kwargs)
File "/home/hussain/workspace/api/lib/python2.7/site-packages/flask/views.py", line 84, in view
return self.dispatch_request(*args, **kwargs)
File "/home/hussain/workspace/api/lib/python2.7/site-packages/flask/views.py", line 149, in dispatch_request
return meth(*args, **kwargs)
File "/home/hussain/workspace/api/lib/python2.7/site-packages/flask_restless/views.py", line 189, in wrapped
return func(*args, **kw)
File "/home/hussain/workspace/api/lib/python2.7/site-packages/flask_restless/views.py", line 1239, in get
return self._search()
File "/home/hussain/workspace/api/lib/python2.7/site-packages/flask_restless/views.py", line 1194, in _search
result = self._paginated(result, deep)
File "/home/hussain/workspace/api/lib/python2.7/site-packages/flask_restless/views.py", line 981, in _paginated
for x in instances[start:end]]
File "/home/hussain/workspace/api/lib/python2.7/site-packages/sqlalchemy/orm/query.py", line 2228, in __getitem__
return list(res)
File "/home/hussain/workspace/api/lib/python2.7/site-packages/sqlalchemy/orm/loading.py", line 73, in instances
rows = [process[0](row, None) for row in fetch]
File "/home/hussain/workspace/api/lib/python2.7/site-packages/sqlalchemy/orm/loading.py", line 455, in _instance
populate_state(state, dict_, row, isnew, only_load_props)
File "/home/hussain/workspace/api/lib/python2.7/site-packages/sqlalchemy/orm/loading.py", line 305, in populate_state
populator(state, dict_, row)
File "/home/hussain/workspace/api/lib/python2.7/site-packages/sqlalchemy/orm/strategies.py", line 169, in fetch_col
dict_[key] = row[col]
ValueError: int_to_boolean only accepts None, 0 or 1
How do I tackle this issue? Please help me out.