Select statement in cases with sqlalchemy - postgresql

We are implementing a workflow engine with SQLAlchemy.
Two tables in our model are:
class DbAttribute(Base):
__tablename__ = "db_dbattribute"
id = Column(Integer, primary_key = True)
dbnode_id = Column(Integer, ForeignKey('db_dbnode.id'))
key = Column(String(255))
datatype = Column(String(10))
tval = Column(String, default='')
fval = Column(Float, default=None, nullable=True)
ival = Column(Integer, default=None, nullable=True)
bval = Column(Boolean, default=None, nullable=True)
dval = Column(DateTime, default=None, nullable=True)
class DbNode(Base):
__tablename__ = "db_dbnode"
id = Column(Integer, primary_key=True)
uuid = Column(UUID(as_uuid=True), default=uuid_func)
type = Column(String(255), index=True)
label = Column(String(255), index=True, nullable=True)
description = Column(Text(), nullable=True)
ctime = Column(DateTime(timezone=True), default=timezone.now)
mtime = Column(DateTime(timezone=True), default=timezone.now)
Attributes are related to a Node via the dbnode_id foreign key.
I am now working on a query that would return an attribute value (for example tval) and None if this row does not exists because the key is not the right one. This is working on aliased classes now:
select_stmt =select([aliased_attributes.tval]).select_from(
aliased_attributes
).where(and_(
aliased_attributes.key==attrkey,
aliased_attributes.dbnode_id==aliased_node.id
))
exists_stmt = exists(select_stmt)
entity = case([
(
exists_stmt,
select_stmt
),
(
text('true'),
None
)
])
This exits now with the following error:
sqlalchemy.exc.ProgrammingError: (psycopg2.ProgrammingError) syntax error at or near "SELECT"
I am using SQLAlchemy 1.0.12 and postgresql 9.4.
Any help on what I missed or other ways this could be done better are greatly appreciated
Cheers

Why not just use simple outerjoin?
attrkey = 'my_attr_key'
q = (
session
.query(
DbNode.label,
DbAttribute.tval,
)
.outerjoin(
DbAttribute,
and_(
DbAttribute.dbnode_id == DbNode.id,
DbAttribute.key == attrkey,
)
)
)

Related

EF Core Filtered Include with Select

Sorry for my English.
I ran into a mistake with EF Core 5.0.9 when is use Filtered Include and Select in same time and i don't know is a bug or feature. :)
return await _dbContext.User
.Where(u => !u.TOROLT)
.Where(u => ids.Contains(u.Id))
.Include(u => u.EventUsers.Where(eu => !eu.TOROLT && eu.EventId == eventId))
.Select(u => new UserDropDownDtoWithInviteData
{
Id = u.Id,
FirstName = u.FirstName,
LastName = u.LastName,
EventUserId = u.EventUsers.First().Id,
IsCelebrated = u.EventUsers.First().IsCelebrated,
IsEventAdmin = u.EventUsers.First().IsEventAdmin,
IsInviteAccepted = u.EventUsers.First().IsInviteAccepted,
IsInvited = u.EventUsers.First().IsInvited,
})
.ToListAsync();
In this time the first elements is select is not from filtered include just from a normal include. SQL Script from Profiler:
SELECT
[u].[Id],
[u].[FirstName],
[u].[LastName],
(
SELECT TOP(1) [e].[Id]
FROM [dbo].[EventUser] AS [e]
WHERE [u].[Id] = [e].[UserId]) AS [EventUserId],
(
SELECT TOP(1) [e0].[IsCelebrated]
FROM [dbo].[EventUser] AS [e0]
WHERE [u].[Id] = [e0].[UserId]) AS [IsCelebrated],
(
SELECT TOP(1) [e1].[IsEventAdmin]
FROM [dbo].[EventUser] AS [e1]
WHERE [u].[Id] = [e1].[UserId]) AS [IsEventAdmin],
(
SELECT TOP(1) [e2].[IsInviteAccepted]
FROM [dbo].[EventUser] AS [e2]
WHERE [u].[Id] = [e2].[UserId]) AS [IsInviteAccepted],
(
SELECT TOP(1) [e3].[IsInvited]
FROM [dbo].[EventUser] AS [e3]
WHERE [u].[Id] = [e3].[UserId]) AS [IsInvited]
FROM [dbo].[User] AS [u]
WHERE ([u].[TOROLT] <> CAST(1 AS bit))
AND [u].[Id] IN (2, 1, 3, 4, 5)
But if is separate filtered include and select, than it work's fine, but this select complete record and not the part of him from database:
var a = await _dbContext.User
.Where(u => !u.TOROLT)
.Where(u => ids.Contains(u.Id))
.Include(u => u.EventUsers.Where(eu => !eu.TOROLT && eu.EventId == eventId))
.ToListAsync();
return a.Select(u => new UserDropDownDtoWithInviteData
{
Id = u.Id,
FirstName = u.FirstName,
LastName = u.LastName,
EventUserId = u.EventUsers.First().Id,
IsCelebrated = u.EventUsers.First().IsCelebrated,
IsEventAdmin = u.EventUsers.First().IsEventAdmin,
IsInviteAccepted = u.EventUsers.First().IsInviteAccepted,
IsInvited = u.EventUsers.First().IsInvited,
})
.ToList();
Any idea why is this, and how can i solve solve this?
THX
Include is completely ignored if you have custom projection Select, so your filter will be also ignored. It is not a bug, Include works only when you get whole entity from query.
Anyway consider to rewrite your query:
var query =
from u in _dbContext.User
where !u.TOROLT && ids.Contains(u.Id)
from eu in u.EventUsers.Where(eu => !eu.TOROLT && eu.EventId == eventId)
.Take(1)
.DefaultIfEmpty()
select new UserDropDownDtoWithInviteData
{
Id = u.Id,
FirstName = u.FirstName,
LastName = u.LastName,
EventUserId = eu.Id,
IsCelebrated = eu.IsCelebrated,
IsEventAdmin = eu.IsEventAdmin,
IsInviteAccepted = eu.IsInviteAccepted,
IsInvited = eu.IsInvited,
};
var result = await query.ToListAsync();

How to set custmer id for an quote in magento?

I am adding product into cart and tried to map customer id,email to that quote
using the below code
$product_id = 123;
$qty = 1;
$product = Mage::getModel('catalog/product')->load($product_id);
$cart = Mage::getModel('checkout/cart');
$cart->init();
$superAttributeArray = array('151' => '3');
$params = array(
'product' => $product_id,
'qty' => $qty,
'super_attribute' => $superAttributeArray
);
$cart->addProduct($product, $params);
$cart->save();
$currenQuoteId = Mage::getSingleton('checkout/session')->getQuoteId();
$store = Mage::getSingleton('core/store')->load(Mage::app()->getStore()->getId());
$quote = Mage::getModel('sales/quote')->setStore($store)->load($currenQuoteId);
$quote->setCustomerId('1')->setCustomerEmail('test#gmail.com')->setCustomerFirstname('firstname')->setCustomerLastname('lastname');
$quote->save();
When I try to set customerid,email,fname,lname am getting error as "Mage registry key "controller" already exists".
Can anyone help me in fixing this issue?
Something like this might work
$customerObj = Mage::getModel('customer/customer')->load($customerId);
$quoteObj = Mage::getModel('sales/quote')->assignCustomer($customerObj);
$storeId = Mage::app()->getStore()->getId();
$quoteObj->setStore(Mage::getSingleton('core/store')->load($storeId);
$productObj = Mage::getModel('catalog/product')->load($productId);
$quoteItem = Mage::getModel('sales/quote_item')->setProduct($productObj);
$quoteItem->setQuote($quoteObj);
$quoteItem->setQty('1');
$quoteItem->setStoreId($storeId);
$quoteObj->addItem($quoteItem);
$quoteObj->setStoreId($storeId);
$quoteObj->collectTotals();
$quoteObj->save();

Flask Admin doesn't show all fields

I have model like this:
class User(db.Model):
__tablename__ = 'users'
__table_args__ = {'mysql_engine' : 'InnoDB', 'mysql_charset' : 'utf8'}
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80), unique=True)
email = db.Column(db.String(120), unique=True)
_password = db.Column('password', db.String(80))
def __init__(self, username = None, email = None, password = None):
self.username = username
self.email = email
self._set_password(password)
def _set_password(self, password):
self._password = generate_password_hash(password)
def _get_password(self):
return self._password
def check_password(self, password):
return check_password_hash(self._password, password)
password = db.synonym("_password", descriptor=property(_get_password, _set_password))
def __repr__(self):
return '<User %r>' % self.username
I have ModelView:
class UserAdmin(sqlamodel.ModelView):
searchable_columns = ('username', 'email')
excluded_list_columns = ['password']
list_columns = ('username', 'email')
form_columns = ('username', 'email', 'password')
But no matter what i do, flask admin didn't show password field when i'm editing user info. Is there any way ? Even just to edit hash code.
UPDATE: https://github.com/mrjoes/flask-admin/issues/78
Reason why it did not work - Flask-Admin was not able to figure out what to do with SynonymProperty, so it failed to generate form field.
There's a way you can have it working right now:
class UserAdmin(sqlamodel.ModelView):
searchable_columns = ('username', 'email')
excluded_list_columns = ['password']
list_columns = ('username', 'email')
form_columns = ('username', 'email')
def scaffold_form(self):
form_class = super(UserAdmin, self).scaffold_form()
form_class.password = wtf.TextField('Password')
return form_class
I pushed simple fix which adds support for the SynonymProperty, so it will work even without form customization. Unfortunately, I'm in process of adding MongoDB backend, so I won't be able to release new version any time soon.
Just in case, SynonymProperty was superseded by hybrid properties in SQLAlchemy 0.7 and onward, which should be supported by the Flask-Admin.
Much better:
from wtforms.fields import PasswordField
class UserAdmin(sqlamodel.ModelView):
searchable_columns = ('username', 'email')
excluded_list_columns = ['password']
form_overrides = dict(password=PasswordField)

zend framework subquery

I am using zend framework 1.12. I have following query to run.
"SELECT name,(select count(*) from org_quote_template_items where org_quote_template_items.quote_template_id = org_quote_templates.`id` ) as total_line_item FROM `org_quote_templates`"
In my model file , I created it like this. following is my model file.
class default_Model_DbTable_QuoteTemplates extends Zend_Db_Table_Abstract
{
/**
* Name of the original db table
*
* #var string
*/
protected $_name = 'org_quote_templates';
public function getAllTemplate($where){
$select = $this->select();
$subquery = " (SELECT COUNT(*) FROM org_quote_template_items WHERE org_quote_template_items.quote_template_id = org_quote_templates.`id` )";
$select->from(array($this), array('org_quote_templates.*','total_line_items' => new Zend_Db_Expr($subquery)));
$select = $select->where('organization_id = ?',$where['org_id']);
$adapter = new Zend_Paginator_Adapter_DbSelect($select);
$paginator = new Zend_Paginator($adapter);
$paginator->setItemCountPerPage(
Zend_Registry::get('config')->paginator->general);
pr($adapter);
exit;
}
}
I am getting following error when I run the code.
" exception 'Zend_Db_Table_Select_Exception' with message 'Select query cannot join with another table' "
please let me know what should I do ?
There is an error in your request. You should have:
$select = $this->select ();
$subquery = "(SELECT COUNT(*) FROM dtempls WHERE order_id = orders.id)";
$select->from ($this, array (
'id',
'total_line_items' => new Zend_Db_Expr ($subquery)
));
I think you have to use setIntegrityCheck(false) for accomplishing that. Check this link
You can try this way in zend
$this->select()
->setIntegrityCheck(false)
->from(array('oqt' => 'org_quote_templates'),array('total_line_item'))
->joinLeft(array('oqti' => 'org_quote_template_items'), 'oqti.quote_template_id = oqt.id', array(count(*) as count))

can`t resolve default schema in zend_db_select

why zend_db_select does not pick up schema from config file? and how can i fix it?
config:
resources.database.adapter = "Oracle"
resources.database.params.dbname = "(DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = x.x.x.x)(PORT = 1521)) (CONNECT_DATA = (SID = xx)))"
resources.database.params.username = ''
resources.database.params.password = ''
resources.database.params.trace =
resources.database.params.schema = YYY
select:
$select->from(
array('pm' => 'tab_1'),
array(
'pm_id',
'status',
'pm_status',
'pm_tabno',
'pm_cardno',
'pm_start_dt',
'pm_endtk_dt',
'pm_signature',
'pm_servrec_no',
'pm_isdirector'
)
)
->joinLeft(
array('pa' => 'tab_2'),
'pm.pm_id = pa.pa_pm',
array(
'PRL_NAME',
'PRF_NAME',
'PRS_NAME'
)
)
->joinLeft(
array('ddpst' => 'tab_3'),
'pm.status = ddpst.dic_value',
'dic_name'
)
->joinLeft(
array('pst' => 'tab_4'),
'pm.pm_status = pst.dic_value',
'dic_sname'
)
->where(
'pa.status = 1'
);
result:
SELECT z2.*
FROM (
SELECT z1.*, ROWNUM AS "zend_db_rownum"
FROM (
SELECT pm.pm_id, pm.status, pm.pm_status, pm.pm_tabno, pm.pm_cardno, pm.pm_start_dt, pm.pm_endtk_dt, pm.pm_signature, pm.pm_servrec_no, pm.pm_isdirector, pa.PRL_NAME, pa.PRF_NAME, pa.PRS_NAME, ddpst.dic_name, pst.dic_sname FROM tab_1 pm
LEFT JOIN tab_2 pa ON pm.pm_id = pa.pa_pm
LEFT JOIN tab_3 ddpst ON pm.status = ddpst.dic_value
LEFT JOIN tab_4 pst ON pm.pm_status = pst.dic_value WHERE (pa.status = 1) ORDER BY PRL_NAME ASC
) z1
) z2
WHERE z2."zend_db_rownum" BETWEEN 1 AND 50
Schema doesn't appear to be a valid parameter accepted by Zend_Application_Resrouce_Db or Zend_Db_Adapter_Oracle. You can set the schema from your DbTable classes if you are using Zend_Db_Table_Abstract to define your DbTables.
See Example #4.
rsolved by overriding Zend_Db_Select (_join() for adding default schema) + overriding Zend_Db_Adapter (for returning own Select)