sqlAlchemy filter query by boolean field? - flask

I have a table for porducts with "is_deleted" field. I want to get only rows that have "is_deleted" = True
model.py
class ProductsModel(db.Model):
__tablename__ = "products"
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(256), nullable=False)
description = db.Column(db.Text, nullable=False)
price = db.Column(db.Float, nullable=False)
discount = db.Column(db.Float, nullable=False)
gender = db.Column(db.Enum(GenderType), nullable=False)
images = db.relationship("ProductImages", backref="product", lazy="select")
pairs = db.relationship("ProductPair", backref="product", lazy="select")
brand_id = db.Column(db.Integer, db.ForeignKey(BrandModel.id), nullable=False)
category_id = db.Column(db.Integer, db.ForeignKey(CategoryModel.id), nullable=False)
is_deleted = db.Column(db.Boolean, default=False, nullable=False)
I try with:
products = ProductsModel.query.filter_by(is_deleted = True)
And that is convert to:
SELECT products.id AS products_id, products.title AS products_title, products.description AS products_description, products.price AS products_price, products.discount AS products_discount, products.gender AS products_gender, products.brand_id AS products_brand_id, products.category_id AS products_category_id, products.is_deleted AS products_is_deleted
FROM products
WHERE false
When I try to run this, result is False:
print(ProductsModel.is_deleted)
If I manualy try to change SQL query to this and run it, I get correct data:
SELECT products.id AS products_id, products.title AS products_title, products.description AS products_description, products.price AS products_price, products.discount AS products_discount, products.gender AS products_gender, products.brand_id AS products_brand_id, products.category_id AS products_category_id, products.is_deleted AS products_is_deleted
FROM products
WHERE is_deleted is TRUE
** is_ doesn't work - The error is bool doesn't have is_ .

Related

ForeignKey serialized as empty dict and not getting populated with data

I've two models Profile & Product representing One-Many relationship. One profile can have many products. I'm serializing all the fields. The column which has ForeignKey is coming out to be empty dictionary. The following model will make my issue more clear.
from backend_olx import db
from marshmallow import Schema, fields
from datetime import datetime
class Product(db.Model):
id = db.Column(db.Integer, primary_key=True)
created_by = db.Column(db.Integer, db.ForeignKey('profile.id'), nullable=False)
purchased_by = db.Column(db.Integer, db.ForeignKey('profile.id'), nullable=True)
name = db.Column(db.String(50), nullable=False)
price = db.Column(db.Integer, nullable=False)
description = db.Column(db.Text, nullable=False)
def __repr__(self):
return '<Product Name %r>' % self.name
class Profile(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(50), nullable=False, unique=True)
email = db.Column(db.String(100), nullable=False, unique=True)
products_sold = db.relationship('Product', backref='profile_sold', foreign_keys="Product.created_by",lazy=True)
products_purchased = db.relationship('Product', backref='profile_purchased', foreign_keys="Product.purchased_by",lazy=True)
def __repr__(self):
return '<User %r>' % self.username
class ProfileSchema(Schema):
id = fields.Int(dump_only=True)
username = fields.Str()
email = fields.Str()
products_sold = fields.Nested('ProductSchema', many=True)
products_purchased = fields.Nested('ProductSchema', many=True)
class ProductSchema(Schema):
id = fields.Int(dump_only=True)
name = fields.Str()
price = fields.Int()
created_by = fields.Nested('ProfileSchema')
purchased_by = fields.Nested('ProfileSchema')
profile_schema = ProfileSchema()
profiles_schema = ProfileSchema(many=True)
product_schema = ProductSchema()
products_schema = ProductSchema(many=True)
The Nested() method in ProfileSchema is working as expected but it is giving { } in ProductSchema.
I want created_by and purchased_by fields to be populated as well.
How to go about ths?
You can't just pass a foreign key and expect Nested to know what to do about it. You need to pass a relation instead.
Create a relation for both fields and use the relation name in the schema.
I typically use xxx_id for column name and xxx for relation name.
class Product(db.Model):
id = db.Column(db.Integer, primary_key=True)
created_by_id = db.Column(db.Integer, db.ForeignKey('profile.id'), nullable=False)
purchased_by_id = db.Column(db.Integer, db.ForeignKey('profile.id'), nullable=True)
name = db.Column(db.String(50), nullable=False)
price = db.Column(db.Integer, nullable=False)
description = db.Column(db.Text, nullable=False)
# Setup relations here
created_by = db.relationship(...)
purchased_by = db.relationship(...)
class ProductSchema(Schema):
id = fields.Int(dump_only=True)
name = fields.Str()
price = fields.Int()
created_by = fields.Nested('ProfileSchema')
purchased_by = fields.Nested('ProfileSchema')

flask sqlalchemy working with relationship in database

Hi guys am trying to create a database that has 10 tables, each tables consist of users info and so on. I want to be able to know the owner of the data in another database table, using the referral_ID from the UserProfile Table. all i want is to be able to track and know the owner of each data in another database table. well am trying to track a referral system data, which each and every user will only have one account, but not in the case of the blogpost and chatpost. below is my model code:
from datetime import datetime
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy(app)
class UserProfile(db.Model):
__tablename__ = "userprofile"
id = db.Column(db.Integer, primary_key=True)
privilege = db.Column(db.String(5), nullable=True, default='user')
sap_sponsor_ID = db.Column(db.String(10), nullable=False)
sap_ID = db.Column(db.String(10), unique=True, nullable=False)
firstName = db.Column(db.String(50), nullable=False)
lastName = db.Column(db.String(50), nullable=False)
email = db.Column(db.String(120), unique=True, nullable=False)
password = db.Column(db.String(60), nullable=False)
gender = db.Column(db.String(6), nullable=False)
date_of_birth = db.Column(db.String(20), nullable=False)
marital_status = db.Column(db.String(7), nullable=False)
about = db.Column(db.Text, nullable=False)
mobile_number = db.Column(db.Integer, unique=True, nullable=False)
country = db.Column(db.String(60), nullable=False)
state = db.Column(db.String(60), nullable=False)
city = db.Column(db.String(60), nullable=False)
home_address = db.Column(db.String(200), nullable=False)
profile_picture = db.Column(db.String(20), nullable=False, default='default.png')
gap_ID = db.Column(db.Integer, unique=True, nullable=False)
joined_date = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
account_owner = db.relationship('UserWallet', 'UserTeamWallet', 'BlogPost', 'ChatPost', 'PendingTransactions', 'ConfirmedTransactions', 'WithheldTransactions', backref='owner', lazy=True)
def __repr__(self):
return f"Users('''\
'{self.privilege}', '{self.sap_sponsor_ID}', '{self.sap_ID}'\
'{self.firstName}', '{self.lastName}', '{self.email}', '{self.gender}'\
'{self.date_of_birth}', '{self.marital_status}', '{self.about}'\
'{self.mobile_number}', '{self.country}', '{self.state}', '{self.city}'\
'{self.home_address}', '{self.profile_picture}', '{self.gap_ID}'\
'{self.joined_date}'\
''')"
class UserWallet(db.Model):
__tablename__ = "userwallet"
id = db.Column(db.Integer, primary_key=True)
stage = db.Column(db.String(7), nullable=False)
rank = db.Column(db.String(16), nullable=False)
referral = db.Column(db.Integer, nullable=False)
wallet_balance = db.Column(db.Integer, nullable=False)
sap_wallet = db.Column(db.Integer, nullable=False)
sap_activator = db.Column(db.Integer, nullable=False)
sap_team = db.Column(db.Integer, nullable=False)
first = db.Column(db.Integer, nullable=False)
second = db.Column(db.Integer, nullable=False)
third = db.Column(db.Integer, nullable=False)
mem = db.Column(db.Integer, nullable=False)
qua = db.Column(db.Integer, nullable=False)
dis = db.Column(db.Integer, nullable=False)
sen = db.Column(db.Integer, nullable=False)
PB = db.Column(db.Integer, nullable=False)
PS = db.Column(db.Integer, nullable=False)
PG = db.Column(db.Integer, nullable=False)
PP = db.Column(db.Integer, nullable=False)
PS = db.Column(db.Integer, nullable=False)
PR = db.Column(db.Integer, nullable=False)
PD = db.Column(db.Integer, nullable=False)
BN = db.Column(db.Integer, nullable=False)
SN = db.Column(db.Integer, nullable=False)
GN = db.Column(db.Integer, nullable=False)
PN = db.Column(db.Integer, nullable=False)
Sa = db.Column(db.Integer, nullable=False)
RN = db.Column(db.Integer, nullable=False)
DN = db.Column(db.Integer, nullable=False)
wallet_owned_by = db.Column(db.String(10), db.ForeignKey('userprofile.sap_ID'), nullable=False)
def __repr__(self):
return f"UserWallet('''\
'{self.stage}', '{self.rank}', '{self.referral}', '{self.wallet_balance}'\
'{self.sap_wallet}', '{self.sap_activator}', '{self.sap_team}'\
'{self.first}', '{self.second}', '{self.third}', '{self.mem}'\
'{self.qua}', '{self.dis}', '{self.sen}'\
'{self.PB}', '{self.PS}', '{self.PG}', '{self.PP}', '{self.PS}'\
'{self.PR}', '{self.PD}', '{self.BN}', '{self.SN}', '{self.GN}'\
'{self.PN}', '{self.Sa}', '{self.RN}', '{self.DN}'\
''')"
class UserTeamWallet(db.Model):
__tablename__ = "userteamwallet"
id = db.Column(db.Integer, primary_key=True)
my_team = db.Column(db.Integer, nullable=False)
team_mem = db.Column(db.Integer, nullable=False)
team_qua = db.Column(db.Integer, nullable=False)
team_dis = db.Column(db.Integer, nullable=False)
team_sen = db.Column(db.Integer, nullable=False)
TB = db.Column(db.Integer, nullable=False)
TS = db.Column(db.Integer, nullable=False)
TG = db.Column(db.Integer, nullable=False)
TP = db.Column(db.Integer, nullable=False)
TS = db.Column(db.Integer, nullable=False)
TR = db.Column(db.Integer, nullable=False)
TD = db.Column(db.Integer, nullable=False)
team_wallet_owned_by = db.Column(db.String(10), db.ForeignKey('userprofile.sap_ID'), nullable=False)
def __repr__(self):
return f"UserTeamWallet('''\
'{self.my_team}', '{self.team_mem}', '{self.team_qua}'\
'{self.team_dis}', '{self.team_sen}', '{self.TB}'\
'{self.TS}', '{self.TG}', '{self.TP}', '{self.TS}'\
'{self.TR}', '{self.TD}'\
''')"
class BlogPost(db.Model):
__tablename__ = "blogpost"
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(500), nullable=False)
post_picture = db.Column(db.String(20), nullable=False, default='default_post.png')
date_posted = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
content = db.Column(db.Text, nullable=False)
blog_posted_by = db.Column(db.String(10), db.ForeignKey('userprofile.sap_ID'), nullable=False)
def __repr__(self):
return f"BlogPost('{self.title}', '{self.date_posted}', '{self.post_picture}', '{self.content}')"
class ChatPost(db.Model):
__tablename__ = "chatpost"
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(500), nullable=False)
chat_picture = db.Column(db.String(20), nullable=False, default='default_chat.png')
date_posted = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
content = db.Column(db.Text, nullable=False)
chat_posted_by = db.Column(db.String(10), db.ForeignKey('userprofile.sap_ID'), nullable=False)
def __repr__(self):
return f"ChatPost('{self.title}', '{self.date_posted}', '{self.chat_picture}', '{self.content}')"
class EmailNewsLetter(db.Model):
__tablename__ = "emailnewsletter"
id = db.Column(db.Integer, primary_key=True)
email = db.Column(db.String(120), unique=True, nullable=False)
applied_date = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
def __repr__(self):
return f"EmailNewsLetter('{self.email}', '{self.applied_date}')"
class UserCommitsQuestion(db.Model):
__tablename__ = "usercommitsquestion"
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(100), nullable=False)
email = db.Column(db.String(120), unique=True, nullable=False)
subject = db.Column(db.String(500), nullable=False)
message = db.Column(db.Text, nullable=False)
submit_date = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
def __repr__(self):
return f"UserCommitsQuestion('{self.name}', '{self.email}', '{self.subject}', '{self.message}', '{self.submit_date}')"
class PendingTransactions(db.Model):
__tablename__ = "pendingtransactions"
id = db.Column(db.Integer, primary_key=True)
firstName = db.Column(db.String(50), nullable=False)
lastName = db.Column(db.String(50), nullable=False)
sap_ID = db.Column(db.String(10), unique=True, nullable=False)
added_date = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
pmethod = db.Column(db.String(100), nullable=False)
ee = db.Column(db.String, nullable=False)
unt = db.Column(db.String, nullable=False)
hash = db.Column(db.String(60), nullable=False)
pending_owned_by = db.Column(db.String(10), db.ForeignKey('userprofile.sap_ID'), nullable=False)
def __repr__(self):
return f"PendingTransactions('''\
'{self.firstName}', '{self.lastName}', '{self.sap_ID}'\
'{self.added_date}', '{self.pmethod}', '{self.ee}'\
'{self.unt}', '{self.hash}'\
''')"
class ConfirmedTransactions(db.Model):
__tablename__ = "confirmedtransactions"
id = db.Column(db.Integer, primary_key=True)
firstName = db.Column(db.String(50), nullable=False)
lastName = db.Column(db.String(50), nullable=False)
sap_ID = db.Column(db.String(10), unique=True, nullable=False)
added_date = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
pmethod = db.Column(db.String(100), nullable=False)
ee = db.Column(db.String, nullable=False)
unt = db.Column(db.String, nullable=False)
hash = db.Column(db.String(60), nullable=False)
pending_owned_by = db.Column(db.String(10), db.ForeignKey('userprofile.sap_ID'), nullable=False)
def __repr__(self):
return f"PendingTransactions('''\
'{self.firstName}', '{self.lastName}', '{self.sap_ID}'\
'{self.added_date}', '{self.pmethod}', '{self.ee}'\
'{self.unt}', '{self.hash}'\
''')"
class WithheldTransactions(db.Model):
__tablename__ = "withheldtransactions"
id = db.Column(db.Integer, primary_key=True)
firstName = db.Column(db.String(50), nullable=False)
lastName = db.Column(db.String(50), nullable=False)
sap_ID = db.Column(db.String(10), unique=True, nullable=False)
added_date = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
pmethod = db.Column(db.String(100), nullable=False)
ee = db.Column(db.String, nullable=False)
unt = db.Column(db.String, nullable=False)
hash = db.Column(db.String(60), nullable=False)
pending_owned_by = db.Column(db.String(10), db.ForeignKey('userprofile.sap_ID'), nullable=False)
def __repr__(self):
return f"PendingTransactions('''\
'{self.firstName}', '{self.lastName}', '{self.sap_ID}'\
'{self.added_date}', '{self.pmethod}', '{self.ee}'\
'{self.unt}', '{self.hash}'\
''')"
but when a tried to create a demo data input into the database table UserProfile it return the below error message:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<string>", line 2, in __init__
File "C:\Users\pc\Desktop\sapWeb\venv\lib\site-packages\sqlalchemy\orm\instrumentation.py", line 388,
in _new_state_if_none
state = self._state_constructor(instance, self)
File "C:\Users\pc\Desktop\sapWeb\venv\lib\site-packages\sqlalchemy\util\langhelpers.py", line 893, in
__get__
obj.__dict__[self.__name__] = result = self.fget(obj)
File "C:\Users\pc\Desktop\sapWeb\venv\lib\site-packages\sqlalchemy\orm\instrumentation.py", line 214,
in _state_constructor
self.dispatch.first_init(self, self.class_)
File "C:\Users\pc\Desktop\sapWeb\venv\lib\site-packages\sqlalchemy\event\attr.py", line 322, in
__call__
fn(*args, **kw)
File "C:\Users\pc\Desktop\sapWeb\venv\lib\site-packages\sqlalchemy\orm\mapper.py", line 3411, in
_event_on_first_init
configure_mappers()
File "C:\Users\pc\Desktop\sapWeb\venv\lib\site-packages\sqlalchemy\orm\mapper.py", line 3299, in
configure_mappers
mapper._post_configure_properties()
File "C:\Users\pc\Desktop\sapWeb\venv\lib\site-packages\sqlalchemy\orm\mapper.py", line 1965, in
_post_configure_properties
prop.init()
File "C:\Users\pc\Desktop\sapWeb\venv\lib\site-packages\sqlalchemy\orm\interfaces.py", line 197, in
init
self.do_init()
File "C:\Users\pc\Desktop\sapWeb\venv\lib\site-packages\sqlalchemy\orm\relationships.py", line 2077,
in do_init
self._process_dependent_arguments()
File "C:\Users\pc\Desktop\sapWeb\venv\lib\site-packages\sqlalchemy\orm\relationships.py", line 2117,
in _process_dependent_arguments
expression._only_column_elements(val, attr)
File "C:\Users\pc\Desktop\sapWeb\venv\lib\site-packages\sqlalchemy\sql\elements.py", line 4801, in
_only_column_elements
raise exc.ArgumentError(
sqlalchemy.exc.ArgumentError: Column-based expression object expected for argument 'primaryjoin';
got: '<class 'run.BlogPost'>', type <class 'flask_sqlalchemy.model.DefaultMeta'>
any other method that will be more easier than this will be accomodated thanks alot.

SQLAlchemy filter all relationships

so I have these four tables
class ClimbingHallSectionModel(BaseModel):
__tablename__ = 'climbing_hall_section'
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
name = db.Column(db.String(50), nullable=False)
climbing_hall_id = db.Column(db.Integer, db.ForeignKey('climbing_hall.id', ondelete='CASCADE'), nullable=False)
walls = db.relationship('ClimbingWallModel', lazy='select', passive_deletes=True)
class ClimbingWallModel(BaseModel):
__tablename__ = 'climbing_wall'
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
name = db.Column(db.String(50), nullable=False)
climbing_hall_section_id = db.Column(db.Integer, db.ForeignKey('climbing_hall_section.id', ondelete='CASCADE'), nullable=False)
height = db.Column(db.Integer)
lines = db.relationship('LineModel', lazy='select', passive_deletes=True)
class LineModel(BaseModel):
__tablename__ = 'line'
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
name = db.Column(db.String(50), nullable=False)
climbing_wall_id = db.Column(db.Integer, db.ForeignKey('climbing_wall.id', ondelete='CASCADE'), nullable=False)
routes = db.relationship('RouteModel', lazy='select', passive_deletes=True)
class RouteModel(BaseModel):
__tablename__ = 'route'
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
name = db.Column(db.String(100), nullable=False)
active = db.Column(db.Boolean, nullable=False, default=True)
line_id = db.Column(db.Integer, db.ForeignKey('line.id', ondelete='CASCADE'), nullable=False)
I want to query all sections where the attribute active of the route table is true.
I tried the following query:
sections = (db.session.query(ClimbingHallSectionModel)
.join(ClimbingWallModel)
.join(LineModel)
.join(RouteModel)
.filter(RouteModel.active==True).all())
This query returns indeed only these sections which contains routes with the attribute active set to true.
However if I now acces the routes of one of the sections with sections.walls[0].lines[0].routes, I get all routes of the selected line including the routes where active is set to false.
For me it looks like that the filter only works correctly on the ClimbingHallSection level but then is not passed to the related tables.
Of course I could do something like this
sections = (db.session.query(ClimbingHallSectionModel, ClimbingWallModel, LineModel, RouteModel)
.select_from(ClimbingHallSectionModel)
.join(ClimbingWallModel)
.join(LineModel)
.join(RouteModel)
.filter(RouteModel.active==True).all())
But this would return a list of tubles:
sections = [
(<ClimbingHallSectionMode 1>, <ClimbingWallModel 1>, <LineModel 1>, <RouteModel 1>),
(<ClimbingHallSectionMode 1>, <ClimbingWallModel >, <LineModel 1>, <RouteModel 2>),...]
I don't know if this is even possible but how can I "pass" the filter arguments to all related tables so that the a section would only contain theses wall which containing lines which contain only routes with active set to true?
Here's a (currently partial) demonstration of the joinedload option.
Change your RouteModel model so that relationships adorn the parent table:
class ClimbingHallSectionModel(BaseModel):
__tablename__ = 'climbing_hall_section'
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
name = db.Column(db.String(50), nullable=False)
climbing_hall_id = db.Column(db.Integer, db.ForeignKey('climbing_hall.id', ondelete='CASCADE'), nullable=False)
walls = db.relationship('ClimbingWallModel', lazy='select', passive_deletes=True)
class ClimbingWallModel(BaseModel):
__tablename__ = 'climbing_wall'
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
name = db.Column(db.String(50), nullable=False)
climbing_hall_section_id = db.Column(db.Integer, db.ForeignKey('climbing_hall_section.id', ondelete='CASCADE'), nullable=False)
height = db.Column(db.Integer)
lines = db.relationship('LineModel', lazy='select', passive_deletes=True)
class LineModel(BaseModel):
__tablename__ = 'line'
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
name = db.Column(db.String(50), nullable=False)
climbing_wall_id = db.Column(db.Integer, db.ForeignKey('climbing_wall.id', ondelete='CASCADE'), nullable=False)
routes = db.relationship('RouteModel', lazy='select', passive_deletes=True)
class RouteModel(BaseModel):
__tablename__ = 'route'
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
name = db.Column(db.String(100), nullable=False)
active = db.Column(db.Boolean, nullable=False, default=True)
line_id = db.Column(db.Integer, db.ForeignKey('line.id', ondelete='CASCADE'), nullable=False)
rev_routes = db.relationship('LineModel', back_populates='routes')
Then, this query ought to give you the related table rows you need, at least for LineModel table:
sections = (db.session.query(RouteModel)
.options(joinedload(RouteModel.rev_routes))
.filter(RouteModel.active==True).all())
For each section in sections, iterate section.rev_routes to access filtered rows in that related table. The joinedload concept does not work (AFAIK) in a sequence of chained relationships, but this may be a start.

Many to Many - Association Object query based on extra association field

I have a many to many association Object relationship. The association object has an extra field for a timestamp. The idea is to only return the associated relationship if the timestamp of the association is within a specific time frame.
models.py
from rvt import db
from sqlalchemy_utils import IPAddressType
class ReportAssociation(db.Model):
id = db.Column(db.Integer, primary_key=True)
entity_id = db.Column(db.Integer, db.ForeignKey('entity.id'))
report_id = db.Column(db.Integer, db.ForeignKey('report_map.id'))
timestamp = db.Column(db.DateTime)
report_map = db.relationship('ReportMap', back_populates='entities')
entity = db.relationship('Entity', back_populates='report_maps')
__table_args__ = (
db.UniqueConstraint('entity_id', 'report_id', 'timestamp'),
)
def __repr__(self):
return f'ReportAssociation: {self.entity} {self.report_map} - {self.timestamp}'
class Entity(db.Model):
id = db.Column(db.Integer, primary_key=True)
ip_address = db.Column(IPAddressType, unique=True, nullable=False)
hostname = db.Column(db.String(64), index=True, nullable=True)
region = db.Column(db.String(32), index=True, nullable=True)
geo = db.Column(db.String(32), index=True, nullable=True)
city = db.Column(db.String(32), index=True, nullable=True)
asn = db.Column(db.String(8), index=True, nullable=True)
subnet_desc = db.Column(db.String(256), index=True, nullable=True)
report_maps = db.relationship('ReportAssociation', back_populates='entity', lazy="dynamic")
timestamp = db.Column(db.DateTime)
def __repr__(self):
return f'<Entity {self.ip_address}>'
class ReportMap(db.Model):
id = db.Column(db.Integer, primary_key=True)
pattern = db.Column(db.String(64), nullable=False, unique=True)
name = db.Column(db.String(32), nullable=False, unique=True)
short_name = db.Column(db.String(32), nullable=False, unique=True)
wiki_url = db.Column(db.String(128), nullable=True, unique=False)
entities = db.relationship('ReportAssociation', back_populates='report_map', lazy="dynamic")
def __repr__(self):
return f'<ReportMap {self.name}>'
The problem I am having is with the query. The following works.
>>> e = Entity.query.one()
>>> e
<Entity 101.98.10.156>
>>> for i in e.report_maps.all():
... print(i.timestamp)
...
2019-04-02 21:15:49.985126
2019-04-02 21:15:59.028121
>>> for i in e.report_maps.filter_by(timestamp='2019-04-02 21:15:59.028121'):
... print(i.timestamp)
...
2019-04-02 21:15:59.028121
The problem comes in when I try to use something like below
>>> for i in e.report_maps.filter(timestamp < '2019-04-02 21:15:59.028121'):
... print(i.timestamp)
...
Traceback (most recent call last):
File "<console>", line 1, in <module>
NameError: name 'timestamp' is not defined
Any help would be appreciated. Thanks
When you use filter method you must use ClassName.attribue so can use you last query like this:
e.report_maps.filter(Entity.timestamp < '2019-04-02 21:15:59.028121').all()

Flask-sqlalchemy-Marshmallow nesting Schema not working

Basically what i want to do is, join 2 tables 'users' & 'company' and get the users with their relevant company details .
this is the user model:
class User(db.Model):
__tablename__ = 'user'
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
firstname = db.Column(db.String(10), nullable=False)
lastname = db.Column(db.String(25), nullable=False)
username = db.Column(db.String(250), nullable=False)
email = db.Column(db.String(100), nullable=False)
password = db.Column(db.String(250), nullable=False)
isPasswordReset = db.Column(db.Boolean, nullable=False)
companyId = db.Column(db.Integer, db.ForeignKey(
'company.id'), nullable=True)
and this is the schema
class UserSchema(ma.Schema):
id = fields.Integer()
firstname = fields.String(required=True)
lastname = fields.String(required=True)
username = fields.String(required=True)
email = fields.String(required=True)
password = fields.String(required=True)
isPasswordReset = fields.Boolean(required=True)
companyId = fields.Integer()
company_name = fields.Nested(CompanySchema)
This is the company model:
class Company(db.Model):
__tablename__ = 'company'
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
companyName = db.Column(db.String(100), nullable=True)
companyCode = db.Column(db.String(20), nullable=True)
companyTheme = db.Column(db.String(300), nullable=True)
this is the company schema:
class CompanySchema(ma.Schema):
id = fields.Integer()
companyName = fields.String(required=True)
companyCode = fields.String(required=True)
companyTheme = fields.String(required=True)
and this is the resource-user.py :
users_schema = UserSchema(many=True)
user_schema = UserSchema()
class UsersResource(Resource):
def get(self):
users = db.session.query(User.firstname, Company.companyName).join(
Company, User.companyId == Company.id).all()
if users:
results = users_schema.dump(users).data
return {'status': 'success', 'message': json.dumps(results, default=str)}, 200
and this is output i get :
{
"status": "success",
"message": "[{\"firstname\": \"abc\"}, {\"firstname\": \"xyz\"}]"
}
only user table are shown, not from company table.i have followed a lot of tutorial and stuff for hours. but still couldn't fix it.i'm new to flask and sqlalchemy. please does anyone knows how to correct this?
At first you need to declare relationship object in your sqlalchemy model:
class User(db.Model):
__tablename__ = 'user'
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
firstname = db.Column(db.String(10), nullable=False)
lastname = db.Column(db.String(25), nullable=False)
username = db.Column(db.String(250), nullable=False)
email = db.Column(db.String(100), nullable=False)
password = db.Column(db.String(250), nullable=False)
isPasswordReset = db.Column(db.Boolean, nullable=False)
companyId = db.Column(db.Integer, db.ForeignKey(
'company.id'), nullable=True)
company = db.relationship("Company", backref="parents") # <--
Then in the user schema declare field that represents that object:
class UserSchema(ma.Schema):
id = fields.Integer()
firstname = fields.String(required=True)
lastname = fields.String(required=True)
username = fields.String(required=True)
email = fields.String(required=True)
password = fields.String(required=True)
isPasswordReset = fields.Boolean(required=True)
companyId = fields.Integer()
company = fields.Nested(CompanySchema) # <--
Please notice, that field names must be the same (or you can use attribute argument).
While querying you could simply do:
user_schema = UserSchema()
users = User.query.all()
results = users_schema.dump(users).data
return {'status': 'success', 'message': json.dumps(results, default=str)}, 200
(or return users_schema.dump(users) for testing purposes)
After all you should get output like this:
{
id: 'something',
firstname: 'something',
lastname: 'something',
username: 'something',
email: 'something',
password: 'something',
isPasswordReset: 'something',
company : {
id: 'something',
companyName: 'something',
companyCode: 'something',
companyTheme: 'something',
}
}
Does this cover your needs?