Zend3 Doctrine Entity passing parameters - doctrine-orm

+-----------------+ +------------------------------------+
| item table | | description table |
+----+------+-----+ +----+---------+------+--------------+
| id | name | ... | | id | item_id | lang | text |
+----+------+-----+ +----+---------+------+--------------+
| 1 | 1st | ... | | 1 | 1 | en | english text |
+----+------+-----+ +----+---------+------+--------------+
| 2 | 2nd | ... | | 2 | 1 | de | deutsch text |
+----+------+-----+ +----+---------+------+--------------+
| 3 | 2 | en | english text |
+----+---------+------+--------------+
class Item {
...
/**
* #ORM\OneToMany(targetEntity="\Application\Entity\Desc", mappedBy="item")
*/
protected $description;
...
}
class Desc {
...
/**
* #ORM\ManyToOne(targetEntity="\Application\Entity\Item", inversedBy="description")
* #ORM\JoinColumn(name="item_id", referencedColumnName="id")
*/
protected $item;
/**
* #ORM\Column(name="text")
protected $text;
public function getDesc(/*passing lang*/)
{
//there returned array of values, not single result
return $this->text;
}
...
}
I have two table with OneToMany relatives. I set #ORM comment tag in entities and succesfully get descriptions array in item entity (EN and De lang). How I can to get only one lang description by passing lang argument to description entity without array iteration and excess SQL row in DB query?

In the Item Class, you can do something like this, which will return only the description with the specified language parameter:
/**
*
* #return \Application\Entity\Desc
*/
public function getDescByLanguage($language)
{
$criteria = Criteria::create()
->where(Criteria::expr()->eq("lang", $language))
->setFirstResult(0)
->setMaxResults(1);
$descByLanguage = $this->description->matching($criteria);
return $descByLanguage[0];
}

Related

Dynamodb single table structure for Many to many relation

We have two Entity Categories and Users. It is classic many 2 many relations.
Users can be tagged to multiple category
Category can have multiple users
Access patterns
Get list of categories
Get list of users, with categories users belong to
Get single user, with categories single user belong to
Get List of users in specific category
I tried to model using Adjacency pattern
but I have few confusions on how to query for
Users list and also get all categories each users belong to
If you have a PK containing the Category and an SK containing the User to model the users in each category, you can create a Global Secondary Index (GSI) with the PK pointing to the original table‘s SK (User) and the SK pointing to the original table’s PK (Category).
Table
| PK | SK | ...
| C#1 | U#1 | ...
| C#1 | U#2 | ...
| C#2 | U#1 | ...
| C#2 | U#3 | ...
GSI
| Table_SK | Table_PK | ...
| U#1 | C#1 | ...
| U#1 | C#2 | ...
| U#2 | C#1 | ...
| U#3 | C#2 | ...
Now you can query:
All categories including their respective users (scan Table)
All users in a single category (query Table)
All users including their respective categories (scan GSI)
All categories that a single user belongs to (query GSI)
Update: Extended model to include metadata as per comments
Table
| PK | SK | CAT | USR | Metadata
---------------------------------------
| | DATA | | { ...: ... }
| C#1 | U#1 | C#1 | U#1 | { ...: ... } (copied from user record)
| | U#2 | C#1 | U#1 | { ...: ... } (copied from user record)
---------------------------------------
| | DATA | | { ...: ... }
| C#2 | U#1 | C#1 | U#1 | { ...: ... } (copied from user record)
| | U#3 | C#1 | U#1 | { ...: ... } (copied from user record)
---------------------------------------
| U#1 | DATA | | { ...: ... }
---------------------------------------
| U#2 | DATA | | { ...: ... }
---------------------------------------
| U#3 | DATA | | { ...: ... }
---------------------------------------
GSI_Users
| Table_USR | Table_CAT |
-----------------------
| U#1 | C#1 |
| | C#2 |
-----------------------
| U#2 | C#1 |
-----------------------
| U#3 | C#2 |
-----------------------
GSI_Categories
| Table_CAT | Table_USR |
-----------------------
| C#1 | U#1 |
| | U#2 |
-----------------------
| C#2 | U#1 |
| | U#3 |
-----------------------
Queries:
All Categories (incl their Users): Scan GSI_Categories
All Users (including their Categories): Scan GSI_Users
Specific Category (including metadata): Query Table by C#x and SK=DATA
Specific Category and its Users: Query GSI_Categories by C#x
Specific User (including metadata): Query Table by U#x and SK=DATA
Sepcific User and its Categories: Query GSI_Users by U#x

PowerQuery - Fill missing data according to specific pattern

I am trying to clean data received from an Excel file and transform it using PowerQuery (in PowerBI) into a useable format.
Below a sample table, and what I am trying to do:
| Country | Type of location |
|--------- |------------------ |
| A | 1 |
| | 2 |
| | 3 |
| B | 1 |
| | 2 |
| | 3 |
| C | 1 |
| | 2 |
| | 3 |
As you can see, I have a list of location types for each country (always constant, always the same number per country, ie each country has 3 rows for 3 location types)
What I am trying to do is to see if there is a way to fill the empty cells in the "Country" column, with the appropriate Country name, which would give something like this:
| Country | Type of location |
|--------- |------------------ |
| A | 1 |
| A | 2 |
| A | 3 |
| B | 1 |
| B | 2 |
| B | 3 |
| C | 1 |
| C | 2 |
| C | 3 |
For now I thought about using a series of if/else if conditions, but as there are 100+ countries this doesn't seem like the right solution.
Is there any way to do this more efficiently?
As Murray mentions, the Table.FillDown function works great and is built into the GUI under the Transform tab in the query editor:
Note that it only fills down to replace nulls, so if you have empty strings instead of nulls in those rows, you'll need to do a replacement first. The button for that is just above the Fill button in the GUI and you'd use the dialog box like this
or else just use the M code that this generates instead of the GUI:
= Table.ReplaceValue(#"Previous Step","",null,Replacer.ReplaceValue,{"Country"})
Yes, like you can do in Excel, you can fill down.
From the docs - Table.FillDown
I believe you will need to sort the data correctly first.
Table.FillDown(
Table.FromRecords({
[Place = 1, Name = "Bob"],
[Place = null, Name = "John"],
[Place = 2, Name = "Brad"],
[Place = 3, Name = "Mark"],
[Place = null, Name = "Tom"],
[Place = null, Name = "Adam"]
}),
{"Place"}
)

Find a string in the entire table (all fields, all columns, all rows) in Django

I have a module (table) in my Django app with 24 fields (columns), and I want to search a string in it. I want to see a list that show me which one of the rows has this string in its fields.
Please have a look at this example:
+-----+------+------+---------+------------+------------+------------+-----+-------------+
| id | name | year | country | attribute1 | attribute2 | attribute3 | ... | attribute20 |
+-----+------+------+---------+------------+------------+------------+-----+-------------+
| 1 | Tie | 1993 | USA | Bond | Busy | Busy | ... | Free |
+-----+------+------+---------+------------+------------+------------+-----+-------------+
| 2 | Ness | 1980 | Germany | Free | Busy | Both | ... | Busy |
+-----+------+------+---------+------------+------------+------------+-----+-------------+
| 3 | Both | 1992 | Sweden | Free | Free | Free | ... | Busy |
+-----+------+------+---------+------------+------------+------------+-----+-------------+
| ... | ... | ... | ... | ... | ... | ... | ... | ... |
+-----+------+------+---------+------------+------------+------------+-----+-------------+
| 24 | Lex | 2001 | Russia | Busy | Free | Free | ... | Both |
+-----+------+------+---------+------------+------------+------------+-----+-------------+
What I am looking to get (by using filters, etc.) is something like this: (When I filter the records base on the word "Both" in the entire table and all of the records. Each row that contains "Both" is in the result below)
+----+------+------+---------+------------+------------+------------+-----+-------------+
| id | name | year | country | attribute1 | attribute2 | attribute3 | ... | attribute20 |
+----+------+------+---------+------------+------------+------------+-----+-------------+
| 1 | Ness | 1980 | Germany | Free | Busy | Both | ... | Busy |
+----+------+------+---------+------------+------------+------------+-----+-------------+
| 2 | Both | 1992 | Sweden | Free | Free | Free | ... | Busy |
+----+------+------+---------+------------+------------+------------+-----+-------------+
| 3 | Lex | 2001 | Russia | Busy | Free | Free | ... | Both |
+----+------+------+---------+------------+------------+------------+-----+-------------+
You can see that the string ("Both") appears in different rows in different columns. (one "Both" is under the column "attribute3", the other "Both" is under column "Name", and the last "Both" is under column "attribute20".
How you get this result in Django by queryset?
Thanks
Assuming you have modeled the above table as a Django model named Person
from django.db.models import Q
query_text = "your search string"
Person.objects.filter(
Q(name__contains=query_text) |
Q(year__contains=query_text) |
Q(attribute1__contains=query_text)
and so on for all your attributes
)
The above code will do a case sensitie search. if instead you want it to be case insenssitive search, use name__icontains instead of say name__contains in the above code.
As suggested by #rchurch4 in comment and based on this so answer, here's how one could search the entire table with fewer lines of code:
from functools import reduce
from operators import or_
all_fields = Person._meta.get_fields()
search_fields = [i.name for i in all_fields]
q = reduce(or_, [Q(**{'{}__contains'.format(f): search_text}) for f in search_fields], Q())
Person.objects.filter(q)

flask-admin + sqlalchemy - modify "sets" of related records in parent model view

I am building a product admin with flask-admin. Products can have single or multiple variant sets. For example a t-shirt can have a "size" set, containing records for S, M, L. A jacket can have both "size" and "color" (red, green, yellow, etc) sets.
Ideally I'd like the administrators to be able to CRUD all product variants from the product view. All other fields on the product view would just be the regular flask-admin default fields for the model. Example sketch:
I'm new to flask-admin, so before I start hackjobbing this up, is there a previously-trodden path for building out such relationships in the a flask-admin-driven UI? I'm thinking some field override that loads a custom widget (or another model view) either in-page or in a modal window?
A simplified outline of the approach I'm taking with flask-sqlalchemy is below.
products
-----------------------------
| skuid | name |
-----------------------------
| B1234 | Test Product 1 |
-----------------------------
| B1235 | Test Product 2 |
-----------------------------
class Product(db.Model):
__tablename__ = 'products'
skuid = db.Column(db.String(16), primary_key=True)
name = db.Column(db.String(128))
variants = db.relationship("Option", secondary="products_to_options")
products_to_options
------------------------
| skuid | variant_set |
------------------------
| B1234 | B1234_1 |
------------------------
| B1234 | B1234_2 |
------------------------
| B1235 | B1235_1 |
------------------------
class ProductToOption(db.Model):
__tablename__ = 'products_to_options'
skuid = db.Column(db.String(16), db.ForeignKey('products.skuid'), nullable=False)
variant_set = db.Column(db.String(16), db.ForeignKey('options.variant_set'), nullable=False)
products = db.relationship('Product', foreign_keys="ProductToOption.skuid")
variants = db.relationship('Option', foreign_keys="ProductToOption.variant_set")
options
-----------------------------------------------------
| variant_set | code | variant_type | description |
-----------------------------------------------------
| B1234_1 | S | size | Small |
-----------------------------------------------------
| B1234_1 | M | size | Medium |
-----------------------------------------------------
| B1234_1 | L | size | Large |
-----------------------------------------------------
| B1234_2 | RD | color | Red |
-----------------------------------------------------
| B1234_2 | GR | color | Green |
-----------------------------------------------------
| B1234_2 | YL | color | Yellow |
-----------------------------------------------------
| B1235_1 | OK | wood | Oak |
-----------------------------------------------------
| B1235_1 | CH | wood | Cherry |
-----------------------------------------------------
class Option(db.Model):
__tablename__ = 'options'
variant_set = db.Column(db.String(16), nullable=False)
code = db.Column(db.String(8), nullable=False)
variant_type = db.Column(db.String(16), db.ForeignKey('option_types.id'), nullable=False)
description = db.Column(db.String(16), nullable=False)
product = db.relationship("Product", secondary="products_to_options")
type = db.relationship("OptionType", foreign_keys="Option.variant_type")
option_types
------------------------
| id | description |
------------------------
| size | Garment Size |
------------------------
| color | Garment Color|
------------------------
| wood | Wood Type |
------------------------
| ring | Ring Size |
------------------------
| shoe | Shoe Size |
------------------------
class OptionType(db.Model):
__tablename__ = 'option_types'
id = db.Column(db.String(16), primary_key=True)
description = db.Column(db.String(36), nullable=False)
It would appear that you are actually trying something in the line of parent-child-child construction here, where the first child is the set. For instance Product has child Garment Size and its child table holds the Small, Medium and Large sizes. So if you change your db model to this idea, that part could work.
Downside is that, as far as I know, flask-admin cannot (yet) provide a create tab that supports 3 tables (parent, child and its child). That would have to be something you need to build yourself.

How to iterate through a list of ranges in Google Apps Script

I have Google sheet with many names and hours which need to be organized. I tried using built in functions, but this sheet is the result of other inputs on other sheets (so the length of the rows is variable)
Sheet 1
A B C D E T U
Project| Name1 | Hours1 | Name2 | Hours2 | ... | ... | Name10 | Hours10|
————————————————————————————————————————————————————————————————————————
P1 | Larry | 10 | Bob | 20 | ... | ... | Tim | 10 |
P2 | Bob | 15 | Tim | 15 | ... | ... | Larry | 15 |
.... | ... | ... | ... | ... | ... | ... | ... | ... |
Pnth | Tim | 20 | Larry | 10 | ... | ... | Bob | 10 |
So far I have tried to iterate through the whole sheet and used a list of names from which to sort with, but I need it to take on a variable length of rows.
function organize(){
var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var rangeList = sheet.getRangeList(['B1:C','D1:E','F1:G','H1:I','J1:K','L1:M','N1:O','P1:Q','R1:S','T1:U']);
What I want it to look like (on a separate sheet): list of names and total hours
Sheet 2
Name | Total hours | Number Projects Assigned|
——————————————————————————————————————————————
Larry| TOTAL NUMBER | 4 (P1,P2,Pnth) |
Tim | TOTAL NUMBER | 4 (P1,P2,Pnth) |
Bob | TOTAL NUMBER | 4 (P1,P2,Pnth) |
Flow:
Get all the values in the range
Loop through them vertically and then horizontally
Create a object with each name as key and [hours, projects] as value.
Map the object back to a 2D array
Snippet:
function organize(values) {
var out = {};//out object
values.forEach(function(row) {
for (var col = 1, l = row.length; col < l; col += 2) {
var name = row[col];
out[name] = out[name] || [0, 0]; //[hours,projects]
out[name][0] += row[col + 1]; //hours sum
out[name][1]++; //projects sum
}
});
return Object.keys(out).map(function(name) {
return [name, out[name][0], out[name][1]]; //[name, hours and projects]
});
}
If used as a custom function,
=organize(A2:U4)
returns name, hours and projects.