split comma separated JSON - python

I am trying to implement a search functionaltiy for a restaurants, currently in my database the the field menu_type is a varchar, the values are separated by commas
"Burger, Cafe, Italian, American,Irish"
how can I make it so that when somebody searches for "Burger" it will show him all the results which have Burger only as menu_type OR "Burger" is a part of their menu_type
#app.route('/api/restaurants/search/',methods=['GET'])
def get_restaurant():
menu = request.json.get('menu')
restaurant = Restaurant.query.filter_by(menu_type=menu).all()
return jsonify(json_list=[i.serialize for i in restaurant])
my restaurant model:
class Restaurant(db.Model):
__tablename__ ='Restaurant'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(64))
address1 =db.Column(db.String(128))
address2 = db.Column(db.String(32))
phone =db.Column(db.Integer)
lat = db.Column(db.Float(precision='12,10'))
lng = db.Column(db.Float(precision='12,10'))
cost = db.Column(db.Integer)
menu_type = db.Column(db.String(64))
rate =db.Column(db.Float(precision='3,2'))
offer=db.Column(db.String(128))
#property
def serialize(self):
"""Return object data in easily serializeable format"""
return {
'id' : self.id,
'name': self.name,
'address1' : self.address1,
'address2': self.address2,
'phone' : self.phone,
'lat': self.lat,
'lng' : self.lng,
'cost': self.cost,
'menu_type' : self.menu_type,
'rate': self.rate,
'offer' : self.offer
}

Use the following for filtering:
Restaurant = Restaurant.query.filter(Restaurant.menu_type.like('% {0}%').format(menu)).all()
This will give you the result because you are doing a like query.

Related

How to get data from multiple tables using flask-sqlalchemy

Here is my tables.
class maindevotee(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(225))
phonenumber = db.Column(db.String(225))
gothram = db.Column(db.String(225))
date = db.Column(db.String(50))
address = db.Column(db.String(250))
def json(self):
return {'id': self.id, 'name':self.name, 'phonenumber': self.phonenumber, 'gothram': self.gothram,
'date': self.date, 'address': self.address}
class relatives(db.Model):
id = db.Column(db.Integer, primary_key=True)
main_id = db.Column(db.Integer, db.ForeignKey('maindevotee.id'), nullable=False)
name = db.Column(db.String(225))
star = db.Column(db.String(225))
gender = db.Column(db.String(45))
relation = db.Column(db.String(45))
def json(self):
return {'main_id': self.main_id, 'name': self.name, 'star':self.star,
'gender': self.gender, 'relation': self.relation}
class services(db.Model):
id = db.Column(db.Integer, primary_key=True)
main_id = db.Column(db.Integer, db.ForeignKey('maindevotee.id'), nullable=False)
pooja = db.Column(db.String(225))
god = db.Column(db.String(225))
price = db.Column(db.Float)
donation = db.Column(db.String(225))
booking_fromdate = db.Column(db.String(50))
booking_todate = db.Column(db.String(50))
prasadam = db.Column(db.String(225))
def json(self):
return {'main_id': self.main_id, 'pooja': self.pooja, 'god': self.god,
'price': self.price, 'donation': self.donation, 'booking_fromdate': self.booking_fromdate,
'booking_todate': self.booking_todate, 'prasadam': self.prasadam}
How to get data from multiple tables in a single request. Here is my scource code to join the three tables.
If i am try to get data from database it will raise an error.
and the error is AttributeError: 'result' object has no attribute 'get_data'
can i get the data from database using foreign key.
data = db.session.query(maindevotee, relatives, services)\
.filter(maindevotee.phonenumber == 3251469870)\
.join(relatives, maindevotee.id == relatives.main_id)\
.join(services, maindevotee.id == services.main_id)\
.first()
def get_data():
return [data.json(get) for get in data.query.all()]
#app.route('/getdata/<phonenumber>',methods=['GET'])
def getdata():
return jsonify({'Devotee list': data.get_data()})
Correct
data = db.session.query(maindevotee, relatives, services)\
.filter(maindevotee.phonenumber == 3251469870)\
.join(relatives, maindevotee.id == relatives.main_id)\
.join(services, maindevotee.id == services.main_id)\
.first()
to
data = db.session.query(maindevotee, relatives, services)\
.filter(
(maindevotee.phonenumber == '3251469870')
& (maindevotee.id == relatives.main_id)
& (maindevotee.id == services.main_id)
).first()
for more clarifications, ask in the comments.
Upon comment
in
#app.route('/getdata/<phonenumber>',methods=['GET'])
def getdata():
return jsonify({'Devotee list': data.get_data()})
data contains the query results, that do not include the function get_data(), therefore you face the mentioned error.
Try the following modification, I think this is the result form you may want:
#app.route('/getdata/<phonenumber>',methods=['GET'])
def getdata():
return jsonify({**data.maindevotee.json(),**data.relatives.json(),**data.services.json()})
Good Luck

SQL Alchemy - Avoiding recursion in a one-to-many relationship

I apologize in advanced for any lack of explanation, as well as the length of this post. I think the issue is much more simple than I'm making it out to be. I have two models utilizing a one to many relationship. For my InsightModel, I have the json() method displaying the following:
{
name: "insightname",
start: 1,
end: 3,
podcast_id: 1,
podcast: {
name: "podcast1",
wave_data: 1,
length: 2,
host: "Hosterman",
category: "entertain",
pub_date: "11/1",
cover_art_url: "google.com"
}
}
And for my PodcastModel, the json() method displays the following:
{
name: "podcast1",
wave_data: 1,
length: 2,
host: "Hosterman",
category: "entertain",
pub_date: "11/1",
cover_art_url: "google.com",
insights: [
{
name: "insightname",
start: 1,
end: 3,
podcast_id: 1
}
]
}
This works as I need it to, but in order to make it work, I had to create two json() methods for each class, in order to avoid recursion in the PodcastModel that would look like the following:
{
name: "podcast1",
wave_data: 1,
length: 2,
host: "Hosterman",
category: "entertain",
pub_date: "11/1",
cover_art_url: "google.com",
insights: [
{
name: "insightname",
start: 1,
end: 3,
podcast_id: 1,
podcast: {
name: "podcast1",
wave_data: 1,
length: 2,
host: "Hosterman",
category: "entertain",
pub_date: "11/1",
cover_art_url: "google.com",
}
}
]
}
My code for the PodcastModel is:
from db import db
from datetime import datetime
class PodcastModel(db.Model):
__tablename__ = 'podcasts'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(100))
wave_data = db.Column(db.Float(precision=2))
length = db.Column(db.Float(precision=2))
host = db.Column(db.String(80))
category = db.Column(db.String(80))
pub_date = db.Column(db.String(50))
cover_art_url = db.Column(db.String(200))
insights = db.relationship('InsightModel', backref='podcast', lazy='dynamic')
def __init__(self, name, wave_data, length, host, category, pub_date, cover_art_url):
self.name = name
self.wave_data = wave_data
self.length = length
self.host = host
self.category = category
self.pub_date = pub_date
self.cover_art_url = cover_art_url
def json(self):
return {'name': self.name, 'wave_data': self.wave_data, 'length': self.length, 'host': self.host, 'category': self.category, 'pub_date': self.pub_date, 'cover_art_url': self.cover_art_url, 'insights': [insight.json_no_podcast() for insight in self.insights.all()]}
def json_no_insight(self):
return {'name': self.name, 'wave_data': self.wave_data, 'length': self.length, 'host': self.host, 'category': self.category, 'pub_date': self.pub_date, 'cover_art_url': self.cover_art_url}
#classmethod
def find_by_name(cls, name):
# Select * FROM items WHERE name=name LIMIT 1
return cls.query.filter_by(name=name).first()
#classmethod
def find_by_id(cls, _id):
return cls.query.filter_by(id=_id)
And the InsightModel is the following:
from db import db
from models.podcast import PodcastModel
class InsightModel(db.Model):
__tablename__ = 'insights'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(100))
start = db.Column(db.Float(precision=2))
end = db.Column(db.Float(precision=2))
podcast_id = db.Column(db.Integer, db.ForeignKey('podcasts.id'))
#podcast = db.relationship('PodcastModel')
def __init__(self, name, start, end, podcast_id):
self.name = name
self.start = start
self.end = end
self.podcast_id = podcast_id
def json(self):
podcast = PodcastModel.find_by_id(self.podcast_id).first().json_no_insight()
return {'name': self.name, 'start': self.start, 'end': self.end,
'podcast_id': self.podcast_id, 'podcast': podcast}
def json_no_podcast(self):
return {'name': self.name, 'start': self.start, 'end': self.end,
'podcast_id': self.podcast_id}
#classmethod
def find_by_name(cls, name):
# Select * FROM items WHERE name=name LIMIT 1
return cls.query.filter_by(name=name).first()
As you can see, I added the json_no_insights() and json_no_podcast() methods to prevent recursion from happening. However, I'm sure reading this code has already given you a pitted feeling in your stomach and I'm desperate for a better way to write it. Thank you very much for any insight and once again, I apologize the for the length of this post or any lack of explanation.
Make your life easier - use marshmallow.
from marshmallow import Schema, fields
from flask import jsonify
class PodcastSchema(Schema):
name = fields.Str()
wave_data = fields.Float()
length = fields.Float()
host = fields.Str()
category = fields.Str()
pub_date = fields.Str()
cover_art_url = fields.Str()
insights = fields.Nested('InsightSchema')
class InsightSchema(Schema):
name = fields.Str()
start = fields.Float()
end = fields.Float()
podcast_id = fields.Integer()
Then simply dump your data like this:
podcast_schema = PodcastSchema() # for dict (single)
podcasts_schema = PodcastSchema(many=True) # for list (array)
jsonify(podcast_schema.dumps(your_json)
Notice lack of a podcast field in the PodcastSchema - that would cause (without tweaking) an infinite recursion. In case you would need that field, you might try as follows:
class PodcastSchema(Schema):
name = fields.Str()
wave_data = fields.Float()
length = fields.Float()
host = fields.Str()
category = fields.Str()
pub_date = fields.Str()
cover_art_url = fields.Str()
# dump insights without podcast field
insights = fields.Nested('InsightSchema', exclude=('podcast', ))
class InsightSchema(Schema):
name = fields.Str()
start = fields.Float()
end = fields.Float()
podcast = fields.Nested('PodcastSchema')

How do I return single object with JSON in Python with Flask

I have the below code which is trying to return an object back to JSON. I'm trying to return back the MenuItem object to the caller
#Make JSON API
#app.route('/restaurant/<int:restaurant_id>/menu/<int:menu_id>/JSON')
def restaurantMenuJSONONE(restaurant_id,menu_id):
item = session.query(MenuItem).filter_by(id = menu_id).one()
return jsonify(MenuItems=item)
Error I'm getting:
TypeError: <database_setup.MenuItem object at 0xb6071d8c> is not JSON serializable
database_setup.py snips
class MenuItem(Base):
__tablename__ = 'menu_item'
name = Column(String(80), nullable=False)
id = Column(Integer, primary_key=True)
description = Column(String(250))
price = Column(String(8))
course = Column(String(250))
restaurant_id = Column(Integer, ForeignKey('restaurant.id'))
restaurant = relationship(Restaurant)
#JSON
#property
def serialize(self):
#return object
return {
'name' : self.name,
'description' : self.description,
'id' : self.id,
'price' : self.price,
'course' : self.course,
}
Solved it with:
return jsonify(MenuItem=item.serialize)
I also solved it with by creating a list and passing the list in, but its a lot more work than using serialize :)

Filter on relationships

I'm trying to filter upon a relationship. In my db I've got awards and awards categories. I want retrieve only the featured and not nominated awards.
This is my model:
class AwardsAwardsCategory(Base):
__tablename__ = 'awards_awards_categories'
id = Column(Text, primary_key=True, default=generate_unique_id)
awards = relationship("Award")
award_id = Column(Text, ForeignKey("awards.id", ondelete='cascade'))
nomination = Column(Boolean)
def __json__(self, request):
return {
"id": self.id,
"nomination": self.nomination
}
class Award(Base):
__tablename__ = 'awards'
id = Column(Text, primary_key=True, default=generate_unique_id)
type = Column(Text)
featured = Column(Integer)
awards = relationship("AwardsAwardsCategory", lazy='joined')
def __json__(self, request):
return {
"id": self.id,
"type": self.type,
"number_of_awards": len(self.awards),
"featured": self.featured,
}
This is the call I make:
query = self.session.query(Award)
query = query.join(AwardsAwardsCategory.awards)
query = query.filter(Award.featured != 0)
query = query.filter(AwardsAwardsCategory.nomination != True)
q_results = query.all()
This results in the following query:
SELECT awards.id AS awards_id, awards.type AS awards_type, awards.featured AS awards_featured, awards_awards_categories_1.id AS awards_awards_categories_1_id, awards_awards_categories_1.award_id AS awards_awards_categories_1_award_id, awards_awards_categories_1.nomination AS awards_awards_categories_1_nomination
FROM awards_awards_categories JOIN awards ON awards.id = awards_awards_categories.award_id LEFT OUTER JOIN awards_awards_categories AS awards_awards_categories_1 ON awards.id = awards_awards_categories_1.award_id
WHERE awards.featured != 0 AND awards_awards_categories.nomination != true
It is almost correct except the WHERE clause is missing a condition:
AND awards_awards_categories_1.nomination != true
How can I change my code so that it adds the last condition to the WHERE clause.
I ended up filtering on the nomination on the application layer. It's nasty, but it works.
query = self.session.query(Award)
query = query.join(AwardsAwardsCategory.awards)
query = query.filter(Award.featured != 0)
query = query.filter(AwardsAwardsCategory.nomination != True)
q_results = query.all()
# remove all objects from the session in order to keep them in the db.
self.session.expunge_all()
for award_category in q_results:
# keep a separate list of the awards, in order to keep the iteration going as desired
awards = list(award_category)
for award in award_category.awards:
if award.nomination:
awards.remove(award)
def __json__(self, request):
return {
"id": self.id,
"type": self.type,
"number_of_awards": self.number_of_awards,
"featured": self.featured,
}
award_category.number_of_awards = len(awards)
award_category.__json__ = types.MethodType( __json__, a )
If anyone knows a how to do it better in SQLAlchemy please tell me!

how to get execute sql statement for following case in odoo?

I have asset.asset there i have added place1 many2one fields i will create some records through this form .
my requirement is that when i select any location in calendar.event at place the my next field should get only those records which are related to same location
suppose i have created at asset.asset like
1)
name: A1,
place:**karnataka/gulbarga/shahapur
**asset_catg_id:**hardware
**area_id:**hard disk
**asset_modelid_add: qqqq(predifined at other class or model with domain fielter by model_no+make)
**folio_no:**qqqqshahapur(auto populate by combaining location+assermodelid_add)
2)
name: B1,
place:**karnataka/gulbarga/jewargi,
**asset_catg_id:**software
**area_id:**os
**asset_modelid_add: zzzz(predifined at other class or model with domain fielter by model_no+make)
**folio_no:**zzzzjewargi(auto populate by combaining location+assermodelid_add)
i want in calendar.event inherited class when i select location the next field should get asset_modelid_add for that record only i.e in many2many fields like If A1 selected next field should get only karnataka/gulbarga/shahapur ,folio_num as qqqqshahapur
class asset_asset(osv.osv):
_inherit = "asset.asset"
#_name = "asset_asset"
_rec_name= "folio_num"
_columns = {
'name': fields.char('Asset Name', size=64),
'place1': fields.many2one('asset.parentlocation', 'Location'),
'asset_catg_id' : fields.many2one('asset.catg', 'Asset Catg Selection',select=True, required=True),
'area_id' : fields.many2one('asset.name', 'Asset Name Selection', domain="[('asset_catg_id', '=', asset_catg_id)]", select=True, required=True),
'assetmodelid_add' : fields.many2one('agile.portfolio1','Asset Model Code',domain="[('area_id', '=', area_id)]",),
'folio_num' : fields.char('Folio No',),
'asse_line':fields.one2many('asset.line','emp_id','Name Plate'),
'asse_line2':fields.one2many('asset.part','emp_id1','Parts'),
#'assed_modelid':fields.many2one('agile.portfolio1','Asset Model ID',select=True, required=True),
'quantity': fields.char('Quantity',size=64),
'uom': fields.char('Uinit of Measure',size=64),
'model_no' : fields.char('Model', size=64),
#'asset_id':fields.many2one('agile.portfolio','Asset ID'),
}
class asset_parentlocation(osv.osv):
_name="asset.parentlocation"
_rec_name="location_name"
_columns = {
'location_name' : fields.char('Asset Location', required=True),
'parent_location' : fields.many2one('asset.parentlocation','Parent Location'),
'nameee':fields.many2one('ir.attachment','Attachments'),}
def name_get(self, cr, uid, ids, context=None):
if context is None:
context = {}
if not ids:
return []
reads = self.read(cr, uid, ids, ['location_name','parent_location'], context=context)
res = []
for record in reads:
name = record['location_name']
if record['parent_location']:
name = record['parent_location'][1]+' / '+name
res.append((record['id'], name))
return res
**calendar_event.py**
class calendar_event(osv.osv):
_inherit = "calendar.event"
_rec_name = 'number'
_columns = {
'number' : fields.char('Meeting ID',readonly=1),
'place' : fields.many2one('asset.parentlocation','Substation Location',),
'assetmodelid_add' : fields.many2many('agile.portfolio1','Asset Model Code',),
'folio_num' : fields.many2many('asset.asset','asset_asset_rel','super_id','asset_asset_id','Folio Num',),
'inspection_name' : fields.many2many('asset1.inspection','asset1_inspection_rel','super_id','asset1_inspection_id','Inspection Type'),
}
please update answers how to do with sql or onchage both are acceptable
Lets consider a simple example. Suppose we have a many2one field to Product (name: product_id). We now want to change the content on this many2one field based on type selection box(name: type). Now, if I choose type as Service, only service type product should be visible in Product field.
To accomplish this, we have to define on change function on type selection box.
def onchange_type(self,cr,uid,ids, type,context=None):
product_obj = self.pool.get('product.product')
product_ids = product_obj.search(cr,uid, [('type','=',type)])
return {'domain':{'product_id':[('id','in',product_ids)]}}
In your case you will have to replicate above scenario.. Above case I have used in my project.
thanks,

Categories

Resources