Convert UUID to string in Django queryset - json

I have a model with a UUID as primary key.
class Books(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
title = .....
And I have a simple query:
results = Books.objects.all()
All is working fine in terms of saving and retrieving data, but part of the record editing process requires storing records in the session variables which means I get the 'UUID('…') is not JSON serializable' error.
It seems to me, that the simplest answer is to convert the UUID objects to strings immediately after making the initial query, thus preventing multiple changes elsewhere. Does that sound logical? If so, I assume I could do it with some sort of list comprehension. Could someone help with the syntax please? Or direct me on the approach if preferred!
Many thanks.

#you have to use
import json
results = Books.objects.all().values('id')
json_str = json.dumps(results)

Related

Can you construct an ActiveRecord scope with a variable query string?

Setup:
I'm using Ruby on Rails with ActiveRecord and MySQL.
I have a Coupon model.
It has an attribute called query, it is a string which could be run with a where.
For example:
#coupon.query
=> "'http://localhost:3003/hats' = :url OR 'http://localhost:3003/shoes' = :url"`
If I were to run this query it would either pass or fail based on the :url value I pass in.
# passes
Coupon.where(#coupon.query, url: 'http://localhost:3003/hats')
Coupon.where(#coupon.query, url: 'http://localhost:3003/shoes')
# fails
Coupon.where(#coupon.query, url: 'http://localhost:3003/some_other_url')
This query varies between Coupon models, but it will always be compared to the current url.
I need a way to say: Given an ActiveRecord collection #coupons only keep coupons with queries that pass.
The structure of the where is always the same, but the query changes.
Is there any way to do this without a loop? I could potentially have a lot of coupons and I am hoping to do this an ActiveRecord scope. Something like this?
#coupons.where(self.query, url: #url)
Perhaps I need to write a user defined function in my database?
Using multiple variables in a query is easy, but where the thing you are comparing your variable to is also a variable - that has me stumped. Any suggestions very appreciated.
I would agree with Les Nightingill's comment that this looks like something that should probably be solved at a more architectural level. I'd imagine an easy refactoring to extract a new CouponQuery model that's a 1:n table containing multiple entries for a coupon_id for each query url that should pass. Then you could use a simple join like
Coupon.joins(:coupon_query).where(coupon_queries: { url: my_url })
If adding a new table is not an option, and if you're running on a newer MySQL version (>= 5.7), you could consider transforming the query column (or adding a new json_query column) into a MySQL JSON field and using the new JSON_CONTAINS query.
If from the user-side they should be able to manage the queries as a plain text field, you could use a before_save hook on your model to translate this into the separate table structure or JSON format respectively.
But if neither is an option for you and you really need to stick with the query column that stores a plain string, then you could use a LIKE query to match the sub-string 'your-url' = :url:
Coupon.where('url LIKE "%? = :url%"', my_url)
which, if you e.g. pass 'http://localhost:3003/hats' as my_url would return something like this SQL query:
SELECT `coupons`.* FROM `coupons`
WHERE (url LIKE "%'http://localhost:3003/hats' = :url%")

How to use RETURNING for query.update() with sqlalchemy

I want to specify the return values for a specific update in sqlalchemy.
The documentation of the underlying update statement (sqlalchemy.sql.expression.update) says it accepts a "returning" argument and the docs for the query object state that query.update() accepts a dictionary "update_args" which will be passed as the arguments to the query statement.
Therefore my code looks like this:
session.query(
ItemClass
).update(
{ItemClass.value: value_a},
synchronize_session='fetch',
update_args={
'returning': (ItemClass.id,)
}
)
However, this does not seem to work. It just returns the regular integer.
My question is now: Am I doing something wrong or is this simply not possible with a query object and I need to manually construct statements or write raw sql?
The full solution that worked for me was to use the SQLAlchemy table object directly.
You can get that table object and the columns from your model easily by doing
table = Model.__table__
columns = table.columns
Then with this table object, I can replicate what you did in the question:
from your_settings import db
update_statement = table.update().returning(table.id)\
.where(columns.column_name=value_one)\
.values(column_name='New column name')
result = db.session.execute(update_statement)
tuple_of_results = result.fetchall()
db.session.commit()
The tuple_of_results variable would contain a tuple of the results.
Note that you would have to run db.session.commit() in order to persist the changes to the database as you it is currently running within a transaction.
You could perform an update based on the current value of a column by doing something like:
update_statement = table.update().returning(table.id)\
.where(columns.column_name=value_one)\
.values(like_count=table_columns.like_count+1)
This would increment our numeric like_count column by one.
Hope this was helpful.
Here's a snippet from the SQLAlchemy documentation:
# UPDATE..RETURNING
result = table.update().returning(table.c.col1, table.c.col2).\
where(table.c.name=='foo').values(name='bar')
print result.fetchall()

sqlalchemy column that is sql expression with bind parameters

I'm trying to map a class that has a column, that doesn't really exist, but is simply a sql expression that takes bind parameters at query time. The model below is an example of what I'm trying to do.
class House(db.Model):
__tablename__ = 'houses'
id = db.Column(db.Integer, primary_key=True)
#hybrid_property
def distance_from_current_location(self):
# what to return here?
return self.distance_from_current_location
#distance_from_current_location.expression
def distance_from_current_location(cls, latitude, longitude):
return db.func.earth_distance(
db.func.ll_to_earth(latitude, longitude), cls.earth_location)
# defer loading, as the raw value is pretty useless in python
earth_location = deferred(db.Column(EARTH))
Then I'd like to query via flask-sqlalchemy:
latidude = 80.20393
longitude = -90.44380
paged_data = \
House.query \
.bindparams({'latitude': latitude, 'longitude': longitude}) \
.paginate(1, 20, False)
My questions are:
How do I do this? Is it possible to use a hybrid_property like this?
If I can use a hybrid_property, what should the python method return? (there is no python way to interpret this, it should just return whatever the DB expression returned.
latitude and longitude only exist during query time and need to be bound for each query. How do I bind latitude and longitude during query time? The bindparams bit in my code snippet I just made up, but it illustrates what I want to do. Is it possible to do this?
I've read the docs but couldn't find any hybrid_property or method with a bind parameter in the examples...
(Also since this is not a real column, but just something I want to use on my model I don't want this to trigger alembic to generate a new column for it).
Thanks!
You can't do this. distance_from_current_location is not a fake column either, since it depends on query-specific parameters. Imagine you were to write a SQL view for this; how would you write the definition? (Hint: you can't.)
SQLAlchemy uses the identity map pattern, which means that for a particular primary key, only one instance exists in your entire session. How would you handle querying the same instance but with different latitude/longitude values? (The instances returned from the later query would overwrite those returned from the earlier one.)
The correct way to do this is through additional entities at query time, like this:
House.query \
.with_entities(House, db.func.earth_distance(db.func.ll_to_earth(latitude, longitude), House.earth_location)) \
.filter(...)
Or through a hyrbid_method (the usage of which requires passing in latitude and longitude every time):
class House(db.Model):
...
#hybrid_method
def distance_from_current_location(self, latitude, longitude):
# implement db.func.ll_to_earth(latitude, longitude), self.earth_location) **in Python** here
#distance_from_current_location.expression
def distance_from_current_location(cls, latitude, longitude):
...

JSON Queries - Failed to execute

So, I am trying to execute a query using ArcGIS API, but it should match any Json queries. I am kind of new to this query format, so I am pretty sure I must be missing something, but I can't figure out what it is.
This page allows for testing queries on the database before I actually implement them in my code. Features in this database have several fields, including OBJECTID and Identificatie. I would like to, for example, select the feature where Identificatie = 1. If I enter this in the Where field though (Identificatie = 1) an error Failed to execute appears. This happens for every field, except for OBJECTID. Querying where OBJECTID = 1 returns the correct results. I am obviously doing something wrong, but I don't get it why OBJECTID does work here. A brief explanation (or a link to a page documenting queries for JSON, which I haven't found), would be appreciated!
Identificatie, along with most other fields in the service you're using, is a string field. Therefore, you need to use single quotes in your WHERE clause:
Identificatie = '1'
Or to get one that actually exists:
Identificatie = '1714100000729432'
OBJECTID = 1 works without quotes because it's a numeric field.
Here's a link to the correct query. And here's a link to the query with all output fields included.

How to covert a mySql DB into Drupal format tables

Hi there i have some sql tables and i want to convert these in a "Drupal Node Format" but i don't know how to do it. Does someone knows at least which tables i have to write in order to have a full node with all the keys etc. ?
I will give an example :
I have theses Objects :
Anime
field animeID
field animeName
Producer
field producerID
field producerName
AnimeProducers
field animeID
field producerID
I have used the CCK module and i had created in my drupal a new Content Type Anime and a new Data Type Producer that exist in an Anime object.
How can i insert all the data from my simple mysql db into drupal ?
Sorry for the long post , i would like to give you the chance to understand my problem
Thx in advance for your time to read my post
You can use either the Feeds module to import flat CSV files, or there is a module called Migrate that seems promising (albiet pretty intense). Both work on Drupal 6 or 7.
mmmmm.... i think you can export CVS from your sql database and then use
http://drupal.org/project/node_import
to import this cvs data to nodes.....mmmm i don know if there is another non-programmatically way
The main tables for node property data are node and node_revision, have a look at the columns in those and it should be fairly obvious what needs to go in those.
As far as fields go, their storage is predictable so you would be able automate an import (although I don't envy you having to write that!). If your field is called 'field_anime' it's data will live in two tables: field_data_field_anime and field_revision_field_anime which are keyed by the entity ID (in this case node ID), entity type (in the case 'node' itself) and bundle (in this case the name of your node type). You should keep both tables up to date to ensure the revision system functions correctly.
The simplest way to do it though is with PHP and the node API functions:
/* This is for a single node, obviously you'd want to loop through your custom SQL data here */
$node = new stdClass;
$node->type = 'my_type';
$node->title = 'Title';
node_object_prepare($node);
// Fields
$node->field_anime[LANGUAGE_NONE] = array(0 => array('value' => $value_for_field));
$node->field_producer[LANGUAGE_NONE] = array(0 => array('value' => $value_for_field));
// And so on...
// Finally save the node
node_save($node);
If you use this method Drupal will handle a lot of the messy stuff for you (for example updating the taxonomy_index table automatically when adding a taxonomy term field to a node)