SQLAlchemy 'Comparator' object has no attribute 'has_key' - python

I am working with JSON SQLAlchemy column and my query statement needs the 'has_key' attribute, but apparently my 'Comparator' object doesn't have this attribute.
Transaction.query.filter(Transaction.fields.has_key('issuername')).all()
where Transaction.fields is a Column(JSON). I get error "AttributeError: Neither 'InstrumentedAttribute' object nor 'Comparator' object associated with Transaction.fields has an attribute 'has_key'". My SQLAlchemy is latest version 1.09. Am I building this query wrong?

has_key operator is specific to JSONB
The JSONB type includes all operations provided by JSON, including the
same behaviors for indexing operations. It also adds additional
operators specific to JSONB, including JSONB.Comparator.has_key(),
JSONB.Comparator.has_all(), JSONB.Comparator.has_any(),
JSONB.Comparator.contains(), and JSONB.Comparator.contained_by().
For JSON column you can use -> PostgreSQL operator (get JSON object field by key)
Transaction.query.filter(Transaction.fields.op('->')('issuername')!=None).all()

Related

pymodm do not recognised the objects of a model

I have started using pymodm in my project (https://github.com/ypriverol/biocontainers-backend/blob/master/biocontainers/common/models.py). All CRUD operations work very well.
However, when I try to retrieve the list of objects for a specific MongoModel using the objects call:
tool_versions_dic = MongoToolVersion.objects.all()
I got this error:
AttributeError: type object 'MongoToolVersion' has no attribute 'objects'

How to see the underlying query which includes count() in it, in django

I have the following code in a Django 2 project
print(List.objects.filter(user=self.request.user).query)
which prints the SQL query which is constructed
but the following
print(List.objects.filter(user=self.request.user).count().query)
throws error
print(List.objects.filter(user=self.request.user).count().query)
AttributeError: 'int' object has no attribute 'query'
I know why it happens, because count() immediately return the count.
How do I see the query which it constructed
List.objects.filter(user=self.request.user).count()
This line returns count as type int and integer type has no attribute query, but you can see the sql query behind this in your django shell
from django.db import connection
List.objects.filter(user=self.request.user).count()
connection.queries[-1]['sql']
connection.queries returns list of dictionaries in that shell session.
Also don't name your model List. It is a reserved keyword.

Django add many to many relationship from _meta.get_field

So I have the following
b = Brand.objects.create(**model_fields_and_values)
b.save()
and then I try to associate that entry with
b._meta.get_field("myfield").add(value3)
and I get the error 'ManyToManyField' object has no attribute 'add'
How can I create an association using a string and not the field ???
I dont want to use b.myfield.add(value3)
getattr allows you to get an attribute using the attribute name:
getattr(b, 'myfield').add(value3)

Apply Python Code To Sqlalchemy Filters

I'm trying to figure out how to apply python code (like splitting a list) to a sqlalchemy filter. An example is as follows: my database stores a full name as a field in the table. I want to query my database for all people who have a given first name. So what I want to do is something like:
User.query.filter(User.name.split()[0].lower() == 'henry'.lower())
When I try to run this query, I get the error:
AttributeError: Neither 'InstrumentedAttribute' object nor 'Comparator' object associated with User.name has an attribute 'split'
What is the general way to apply python commands like split(), lower(), etc. to my sqlalchemy queries?
SQLAlchemy is constructing a SQL expression, not a Python expression. You can apply SQL functions to the expression by using the func object.
from sqlalchemy import func
User.query.filter(func.lower(func.substring_index(User.name, ' ', 1)) == 'henry')

force object to be `dirty` in sqlalchemy

Is there a way to force an object mapped by sqlalchemy to be considered dirty? For example, given the context of sqlalchemy's Object Relational Tutorial the problem is demonstrated,
a=session.query(User).first()
a.__dict__['name']='eh'
session.dirty
yielding,
IdentitySet([])
i am looking for a way to force the user a into a dirty state.
This problem arises because the class that is mapped using sqlalchemy takes control of the attribute getter/setter methods, and this preventing sqlalchemy from registering changes.
I came across the same problem recently and it was not obvious.
Objects themselves are not dirty, but their attributes are. As SQLAlchemy will write back only changed attributes, not the whole object, as far as I know.
If you set an attribute using set_attribute and it is different from the original attribute data, SQLAlchemy founds out the object is dirty (TODO: I need details how it does the comparison):
from sqlalchemy.orm.attributes import set_attribute
set_attribute(obj, data_field_name, data)
If you want to mark the object dirty regardless of the original attribute value, no matter if it has changed or not, use flag_modified:
from sqlalchemy.orm.attributes import flag_modified
flag_modified(obj, data_field_name)
The flag_modified approach works if one know that attribute have a value present. SQLAlchemy documentation states:
Mark an attribute on an instance as ‘modified’.
This sets the ‘modified’ flag on the instance and establishes an
unconditional change event for the given attribute. The attribute must
have a value present, else an InvalidRequestError is raised.
Starting with version 1.2, if one wants to mark an entire instance then flag_dirty is the solution:
Mark an instance as ‘dirty’ without any specific attribute mentioned.

Categories