Return Django ORM union result in Django-Graphene - postgresql

I am trying to query two separate objects and return them as a single result set. I've tried using a Union and an Interface, but not sure what I'm doing wrong there.
My model:
class BaseActivity(models.Model):
class Meta:
abstract = True
name = models.CharField(db_column="activity_type_name", unique=True, max_length=250)
created_at = CreationDateTimeField()
modified_at = ModificationDateTimeField()
created_by = models.UUIDField()
modified_by = models.UUIDField()
deleted_at = models.DateTimeField(blank=True, null=True)
deleted_by = models.UUIDField(blank=True, null=True)
class Activity(BaseActivity):
class Meta:
db_table = "activity_type"
ordering = ("sort_order",)
id = models.UUIDField(
db_column="activity_type_id",
primary_key=True,
default=uuid.uuid4,
editable=False,
)
sort_order = models.IntegerField()
def __str__(self):
return self.name
class CustomActivity(BaseActivity):
class Meta:
db_table = "organization_custom_activity_type"
id = models.UUIDField(
db_column="organization_custom_activity_type",
primary_key=True,
default=uuid.uuid4,
editable=False,
)
farm = models.ForeignKey("farm.Farm", db_column="organization_id", on_delete=models.DO_NOTHING, related_name="custom_activity_farm")
My schema:
class FarmActivities(graphene.ObjectType):
id = graphene.String()
name = graphene.String()
class ActivityType(DjangoObjectType):
class Meta:
model = Activity
fields = ("id", "name", "requires_crop", "sort_order")
class CustomActivityType(DjangoObjectType):
class Meta:
model = CustomActivity
fields = ("id", "name", "farm")
And the query:
class Query(graphene.ObjectType):
get_farm_activities = graphene.Field(FarmActivities, farm=graphene.String(required=True))
def resolve_get_farm_activities(self, info, farm):
farm_activities = Activity.objects.values("id", "name").filter(
farmtypeactivityrel__farm_type__farm=farm, deleted_at=None
)
custom_activities = CustomActivity.objects.values("id", "name").filter(farm=farm, deleted_at=None)
return list(chain(farm_activities, custom_activities))
With this, I do get a list back from the query, but it's not going thru the resolver when I call getFarmActivities.
Literally the list returns:
ExecutionResult(data={'getFarmActivities': {'id': None, 'name': None}}, errors=None)

How to resolve graphene.Union Type?
That provided the hint I needed to get this working. I had to build a Union that would parse the model and not the schema type.
class FarmActivities(graphene.Union):
class Meta:
types = (ActivityType, CustomActivityType)
#classmethod
def resolve_type(cls, instance, info):
if isinstance(instance, Activity):
return ActivityType
if isinstance(instance, CustomActivity):
return CustomActivityType
return FarmActivities.resolve_type(instance, info)
Which then allowed me to run the query like so:
def resolve_get_farm_activities(self, info, farm):
farm_activities = Activity.objects.filter(
farmtypeactivityrel__farm_type__farm=farm
)
custom_activities = CustomActivity.objects.filter(farm=farm)
return list(chain(farm_activities, custom_activities))
And the API query:
query farmParam($farm: String!)
{
getFarmActivities(farm: $farm)
{
... on CustomActivityType
{
id
name
}
... on ActivityType
{
id
name
}
}
}

Related

Flask SQLAlchemy, IntegrityError, ForeignKeyViolation - Creating relationships between tables

I'm trying to create a Flask app where I can return a list of 'workspaces' from a postgresql database, a list of 'categories and a list of 'projects'.
In projects.py, when a GET method is called, the database will return all of the 'workspaces' and all of the 'categories' and get both the id and name for each, I can then put this in a dropdown button for the user to select. This part of the code works fine.
When a POST method is called, this should add a new row to the 'projects' table to define a new project, along with this should be the workspace_id and the categories_id that the user selected.
This part of the code is not working, I get the following error message:
sqlalchemy.exc.IntegrityError: (psycopg2.errors.ForeignKeyViolation) insert or update on table "projects" violates foreign key constraint "workspace_id"
DETAIL: Key (id)=(19) is not present in table "workspaces".
[SQL: INSERT INTO projects (name, description, category_id, workspace_id, visibility_level, slug) VALUES (%(name)s, %(description)s, %(category_id)s, %(workspace_id)s, %(visibility_level)s, %(slug)s) RETURNING projects.id]
[parameters: {'name': 'Brand New Project', 'description': 'gfhfghfg', 'category_id': '1', 'workspace_id': '1', 'visibility_level': '1', 'slug': 'brand-new-project'}]
models.py:
from sqlalchemy import Column, Integer, String, ForeignKey
from sqlalchemy.orm import relationship
from taskmanagement.database import Base
class Projects(Base):
__tablename__ = 'projects'
id = Column(Integer, primary_key=True)
name = Column(String(140), unique=True)
description = Column(String(140), unique=True)
category_id = Column(Integer, ForeignKey('categories.id'), unique=False, nullable=False)
category = relationship('Categories', lazy=True, uselist=False, primaryjoin="Categories.id == Projects.category_id")
workspace_id = Column(Integer, ForeignKey('workspaces.id'), unique=False, nullable=False)
workspace = relationship('Workspaces', lazy=True, uselist=False, primaryjoin="Projects.workspace_id == Workspaces.id")
visibility_level = Column(Integer, unique=False)
slug = Column(String(240), unique=True)
def __init__(self, name=None, description=None, category_id=None, workspace_id=None, visibility_level=None, slug=None):
self.name = name
self.description = description
self.category_id = category_id
self.workspace_id = workspace_id
self.visibility_level = visibility_level
self.slug = slug
def __repr__(self):
return f'<Projects {self.name!r}>'
class Workspaces(Base):
__tablename__ = 'workspaces'
id = Column(Integer, primary_key=True)
name = Column(String(50), unique=True)
def __init__(self, name=None):
self.name = name
def __repr__(self):
return f'<Workspaces {self.name!r}>'
class Categories(Base):
__tablename__ = 'categories'
id = Column(Integer, primary_key=True)
name = Column(String(50), unique=True)
def __init__(self, name=None):
self.name = name
def __repr__(self):
return f'<Workspaces {self.name!r}>'
Projects.py
#projects.route('/projects/add', methods = ['POST', 'GET'])
def project_add():
if request.method == 'GET':
categories = Categories.query.all()
workspaces = Workspaces.query.all()
categories_results = [
{
"id": category.id,
"name": category.name
} for category in categories]
workspaces_results = [
{
"id": workspace.id,
"name": workspace.name
} for workspace in workspaces]
results = {"categories": categories_results, "workspaces": workspaces_results}
return render_template('project_add.html', title='Add Project', results=results)
else:
name = request.form['project_name']
slug = request.form['project_slug']
description = request.form['project_desc']
visibility_level = request.form['project_visibility']
category_id = request.form['category_id']
workspace_id = request.form['workspace_id']
form_results = {
"name": request.form['project_name'],
"slug": request.form['project_slug'],
"description": request.form['project_desc'],
"visibility_level": request.form['project_visibility'],
"category_id": request.form['category_id'],
"workspace_id": int(request.form['workspace_id'])
}
#return form_results
results = Projects(name, description, category_id, workspace_id, visibility_level, slug)
db_session.add(results)
db_session.commit()
I'm completely stuck of this problem. Can anyone tell me what I'm doing wrong?

Inserting parent/child rows in Hibernate with autoincrement index throws error

I have the following Hibernate classes in Scala, where one Group has many Items. Note that the #Id of the Group class has an autoincrement annotation.
#Entity
#Table(name = "items")
class Item extends Serializable {
#Id
#ManyToOne
#JoinColumn(name="group_sk", nullable=false)
var group: Group = _
#Id
var index: Int = _
var name: String = _
def canEqual(a: Any) = a.isInstanceOf[Item]
override def equals(that: Any): Boolean =
that match {
case that: Item => that.canEqual(this) && this.hashCode == that.hashCode
case _ => false
}
override def hashCode: Int = {
val prime = 31
var result = 1
result = prime * result + group.sk;
result = prime * result + index
return result
}
}
#Entity
#Table(name = "groups")
class Group {
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "group_generator")
#SequenceGenerator(name="group_generator",
sequenceName = "GroupSeq", allocationSize = 1)
var sk: Int = _
#Column(name = "group_name")
var name: String = _
#OneToMany
#JoinColumn(name="group_sk")
var items: java.util.List[Item] = _
}
I try to insert one group with a related item, where both the Group should have an auto incremented Id:
session.beginTransaction
val group = new Group
group.name = "Group name"
group.items = new java.util.ArrayList[Item]()
val item1 = new Item
item1.group = group
item1.index = 1
item1.name = "Item 1"
group.items.add(item1)
session.save(group)
session.getTransaction.commit
The exception I get is
Caused by: javax.persistence.OptimisticLockException: Batch update
returned unexpected row count from update [0]; actual row count: 0;
expected: 1
And the Hibernate sql log shows:
Hibernate: select GroupSeq.nextval from dummy
Hibernate: insert into groups (group_name, sk) values (?, ?)
Hibernate: update items set group_sk=? where index=? and group_sk=?
Note that the last update statement doesn't make sense because you won't update the value of group_sk where the column is also in the condition. Moreover, there's no insert statement of the items table.
How to fix this problem?
You need to set cascade type on your OneToMany relationship to tell Hibernate how to mange Items collection of the Group class. So for example something like this should work:
#OneToMany(cascade=CascadeType.ALL)
#JoinColumn(name="group_sk")
var items: java.util.List[Item] = _

Grails MongoDb: saving map values with domain as value fails

I have 2 domain classes, User and Dog (for example)
class User {
String id
Map<String, Dog> dogs
}
class Dog {
String name
}
My Controller get as an input a json
{"key" : "dogKey", "userId" : "someId", "dogName" : "dog"}
def addDog(){
String key = request.JSON.key
User user = User.get(request.JSON.userId)
String dogName = request.JSON.dog
...
if(! user.dogs){
user.dogs = new HashMap<>(1)
}
user.dogs.put(key, new Dog(name: dogName))
user.save(flush: true)
}
after running the user data # Mongo is:
user:
{ _id:....,
dogs: {
"dogKey": null
}...
}
can someone please explain me what i'm missing?
Thanks!
Roy
may be dog reference is not save in database
def addDog(){
String key = request.JSON.key
User user = User.get(request.JSON.userId)
String dogName = request.JSON.dog
...
if(! user.dogs){
user.dogs = new HashMap<>(1)
}
Dog dog = new Dog(name: dogName)
dog.save(flush:true)
user.dogs.put(key, dog)
user.save(flush: true)
}

Custom searching using tastypie

actually we have 2 models
class Event(Basetable):
title = models.CharField(max_length=150)
event_description = models.TextField()
image = ThumbnailerImageField(upload_to=get_eventlogo_path, resize_source=dict(size=(700, 0), crop='smart'),)
category = models.ManyToManyField("EventCategory")
venue = models.ForeignKey(Venue,null=True)
class Venue(models.Model):
venue = models.CharField(max_length=100)
address1 = models.CharField(max_length=200)
address2 = models.CharField(max_length=200,blank=True)
slug = models.CharField(max_length=150,blank=True,null=True)
country = models.ForeignKey(Countries,null=True,blank=True,on_delete=models.SET_NULL)
state = models.ForeignKey(States,null=True,on_delete=models.SET_NULL)
city = models.ForeignKey(City,null=True,on_delete=models.SET_NULL)
tastypie code
class EventResource(ModelResource):
venue = fields.ForeignKey(VenueResource, 'venue')
class Meta:
queryset = Event.objects.filter(status='P').order_by('-id').distinct()
resource_name = 'eventlist'
filtering = {
"slug": ('exact', 'startswith',),
"title": ALL,
}
my problem is i need to get event result using city which is in venue
ex www.example.com/api/v1/eventlist/?format=json&city="chicago" but it is not coming help me
You have to allow filtering by venue:
filtering = { 'venue': ALL_WITH_RELATIONS
}
This link will work.
www.example.com/api/v1/eventlist/?format=json&venue_city_name="chicago"

Tasty pie search

i have two models
class Business(Basetable):
name = models.CharField(max_length=120)
slug = models.SlugField(max_length=150)
logo=models.OneToOneField("BusinessLogo",null=True,on_delete=models.SET_NULL)
class Address(models.Model):
business = models.ForeignKey("Business", related_name='biz_address')
address1 = models.CharField(max_length=100,null=True)
address2 = models.CharField(max_length=100,null=True)
state = models.ForeignKey(States,null=True,on_delete=models.SET_NULL)
city = models.ForeignKey(City,null=True,on_delete=models.SET_NULL)
view.py
class BusinessResource(ModelResource):
class Meta:
queryset = Business.objects.filter(status='P').order_by('-id')
resource_name = 'business'
filtering = {
'is_black_business': ALL,
'city': ALL_WITH_RELATIONS,
}
def dehydrate(self,bundle):
if buss_address.city:bundle.data['city'] = buss_address.city.name
else:bundle.data['city'] = ''
// i am getting city here
problem is i need to filter the business using city .. how can i do that ? any guess
class BusinessResource(ModelResource):
addresses = fields.ToManyField(AddressResource, 'biz_address')
class Meta:
filtering = {
'addresses': ALL_WITH_RELATIONS,
}
class AddressResource(ModelResource):
city = fields.ToOneField(CityResource, 'city')
class Meta:
filtering = {
'city': ALL_WITH_RELATIONS,
}
Second way is to write custom filter by overriding build_filters and apply_filters methods.