How can I query a ScalarListType in flask_sqlalchemy - flask-sqlalchemy

I want to insert an integer list as a one column datatype in flask_sqlalchemy,
and I found ScalarListType in the package SQLAlchemy-Utils:
from sqlalchemy_utils import ScalarListType
class Foo():
id = db.Column(db.Integer, primary_key=True)
list = db.Column(ScalarListType(int))
I can query for foo by id:
foo = Foo.query.filter(Foo.id==1).first()
Then, foo.list is an integer list like [0, 0, 1, 0]
But, how can I build a query for an index in the list? E.g. something like Foo.list[3]==1
I can't find any clue, help me pleaseļ¼

I'm not sure a ScalarListType will be able to accomplish what you want -- it doesn't look like it's built to be queried by index. See the source code here -- it's just a text column with commas separating the values.
You might be able to hack something together with bare SQL, but it would probably mean using LIKE somewhere, or splitting strings which gets complicated quickly.
In the long run, you might be better off just making a separate columns for this data.

Related

Django - Query: how to decode integer field value with its string value 'on the fly'

maybe it is not good practice but I would like to know if it is possible to decode an integer field value with its string value
I know I should have a specific models linked as thesaurus...
I have a models mymodel
I produce a QuerySet mymodel.objects.values('id','var2','var3','var4') for example
var3 is an integer (0/1) for Yes/No answer
Is it possible to populate my QuerySet with Yes or No instead of its integer value?
You can annotate it, for example:
from django.db.models import Case, CharField, Value, When
QuerySet.objects.values('id', 'var2', 'var4',
new_var3=Case(
When(var3=1, then=Value('Yes')),
default=Value('No'),
output_field=CharField(),
)
)
Note that you however should rename the variable.
That being said, it is not a good idea to use .values(..) or .values_list(..) to eprform serialization. Furthermore it will perform text processing on the database, and often that is not really the core task of a database. Normally serializers [drf-doc] are used for that.

Get common ManyToMany objects with django extra select

class Seller(object):
type = ...
name = ...
cars = models.ManyToManyField(Car)
class PotentialBuyer(object):
name = ...
cars = models.ManyToManyField(Car)
class Car(object):
extra_field = ...
extra_field2 = ...
Suppose I have a relationship like this. I would like to use extra queryset modifier to get the list of cars that are already been picked out by PotentialBuyers when I fetch a seller object. I suppose the query queryset will something like this.
def markPending(self)
return self.extra(select={'pending': 'select images from PotentialBuyer as t ...'})
How can I accomplish this? Is there a better way? I could fetch the seller object and the potential object and do sets, but I'd think it would be cleaner to make it handled by the database. I am using PostgreSQL 9.5.
I think the Exists subquery expression will do what you want. Or at least it'll get you started on the right path. Docs Or you might want to use an aggregate to count the number of them.
Edit: If you need to select the full objects rather than the count, existence or a single entity, then use a Prefetch instance in prefetch_related. https://docs.djangoproject.com/en/2.0/ref/models/querysets/#django.db.models.Prefetch
Not quite the answer, but this is the solution I ended up with and I am satisfied by the performance. Perhaps someone can answer the question later :
from api.models import PotentialBuyer
potentials = PotentialBuyer.objects.filter(owner=user_id, default=True).first().cars.all()
Car.objects.filter(....).annotate(pending=Case(When(id__in=potentials, then=Value(True)), default=Value(False), output_field=BooleanField()))

SSRS if field value in list

I've looked through a number of tutorials and asks, and haven't found a working solution to my problem.
Suppose my dataset has two columns: sort_order and field_value. sort_order is an integer and field_value is a numerical (10,2).
I want to format some rows as #,#0 and others as #,#0.00.
Normally I would just do
iif( fields!sort_order.value = 1 or fields!sort_order.value = 23 or .....
unfortunately, the list is fairly long.
I'd like to do the equivalent of if fields!sort_order.value in (1,2,21,63,78,...) then...)
As recommended in another post, I tried the following (if sort in list, then just output a 0, else a 1. this is just to test the functionality of the IN operator):
=iif( fields!sort_order.Value IN split("1,2,3,4,5,6,8,10,11,15,16,17,18,19,20,21,26,30,31,33,34,36,37,38,41,42,44,45,46,49,50,52,53,54,57,58,59,62,63,64,67,68,70,71,75,76,77,80,81,82,92,98,99,113,115,116,120,122,123,127,130,134,136,137,143,144,146,147,148,149,154,155,156,157,162,163,164,165,170,171,172,173,183,184,185,186,192,193,194,195,201,202,203,204,210,211,212,213,263",","),0,1)
However, it doesn't look like the SSRS expression editor wants to accept the "IN" operator. Which is strange, because all the examples I've found that solve this problem use the IN operator.
Any advice?
Try using IndexOf function:
=IIF(Array.IndexOf(split("1,2,3,4,...",","),fields!sort_order.Value)>-1,0,1)
Note all values must be inside quotations.
Consider the recommendation of #Jakub, I recommend this solution if
your are feeding your report via SP and you can't touch it.
Let me know if this helps.

Using Orderby on BatchedJoinBlock(Of T1, T2) - Dataflow (Task Parallel Library)

I'm just looking to be able to sort the results of a BatchedJoinBlock (http://msdn.microsoft.com/en-us/library/hh194683.aspx) so that the different results of the different targets stay together. I will explain! Example in some pseudo-code:
Dim batchedJoin = New BatchedJoinBlock(Of String, object)(4)
batchedJoin.Target1.Post("String1Target1")
batchedJoin.Target2.Post(CType(BuildIt, StringBuilder1))
batchedJoin.Target1.Post("String1Target2")
batchedJoin.Target2.Post(CType(BuildIt, StringBuilder2))
Dim results = batchedJoin.Receive()
'This sorts one result...
Dim SortByResult = results.Item1.OrderBy(Function(item) item.ToString, New NaturalStringComparer)
Basically I've got a string and an object, the SortByResult variable above sorts the strings exactly as I'd like them to sort. I'm looking for a way to get the objects that used to be at the same index number in target2 into the same order. e.g. if "String1Target1" changes order I'd like to somehow reliably refer to/pair it together with "StringBuilder1". The actual end result just needs to be that the objects (target2) are sorted in the order that is dictated by the strings being sorted (target1). Something like:
Dim EndResult = results.Item2.OrderBy(strings in target1)
but I'll gladly take an intermediate solution! I've also tried using a dictionary (results.Item2.ToDictionary) with the string as a key (which would also be a fine solution) but it's a bit beyond my ken using lamba expressions in the proper context. I can realistically do this in several steps with a list or something, but I'm trying to get something more efficient/learn something, and it seems like there's a lot of default options with the results of the jointblock that I'm just not experienced enough to use. Thanks in advance for any help you can provide!
To me, it looks like you don't actually want BatchedJoinBlock, because the two pieces of data always come together. A better option for that would be a BatchBlock of Tuple<string, object>. When you have that, you can then use LINQ directly to sort each batch:
results.OrderBy(Function(tuple) tuple.Item1)

Find a Value in Two Dimensional Array on VB.NET

I declared my Array:
Dim invoice_discountitems(100, 100) As String
Set Values into array:
For i As Int16 = 0 To data_set.Tables("discount_items").Rows.Count - 1
invoice_discountitems(i, 1) = data_set.Tables("discount_items").Rows(0).Item("item_code")
invoice_discountitems(i, 2) = data_set.Tables("discount_items").Rows(0).Item("discountitem_average")
Next
Now I try to find a single value:
Dim res As String
res = Array.IndexOf(invoice_discountitems, "FO1506")
MsgBox(res)
But, I get this error :(
"Only single dimension arrays are supported here"
This is a fundamentally wrong approach - for a number of reasons
You're treating ALL the data points as Strings
You're not taking advantage of DB optimisations like indices
You're loading data into memory that you're never going to use (at least int he example)
The Nicest way to do it would be with Linq-To-Entities:
Dim Record = MyDBContext.Discount_Items.Where(function(x) x.ItemCode = "FO1506").Single
Console.WriteLine(Record.discountitem_average);
If you're stuck with your current Data Access Layer, you need to modify the SQL being executed to only return the information you're interested in. Without more information, I can't provide decent example code but you want the SQL to end up looking like this...
SELECT itemcode,
discountitem_average,
[Other fields],
FROM MyDatabase.M
EDIT: To Clarify, there are a number of ways to access data in a database. The one I prefer is LINQ-To-Entities (Have a look through this tutorial).
In short, you add a new Item to your project and point it at your database. This becomes your "Database Context" - it represents the database and that's how you run queries.
Project -> Add -> New Item...
Select ADO.Net Entity Data Model (Linq-To-Entities is almost Identical to Linq-To-Sql but more recent and better supported - use Entities until you know the difference)
Call it something like MyDBContext
When prompted, choose "Generate From Database" and point it at your database.
It's worth noting that the designer takes advantage of information in the database like Foreign Key Constraints - So the better your database is designed, the better the model it will create.
Then, you refer to it in code as shown in my first example.
First of all IndexOf return int as index!
To get the index of string
Try:
Dim i As int
Dim j As int
i = Array.IndexOf(invoice_discountitems.OfType(Of String)().ToArray(), "FO1506")
j = i MOD 100
i= i/100
MsgBox(i+" "+j)
(I use c# but I think it's not different)