How to replace search method with sql query in odoo - python

When I have too many product and I used the following filter, the loading time is long.So I want to replace with query.How can I change my search into query?I know the basic query but cant convert my search into query because I don't know how to use for with_context in query.
class valuation_report(models.Model):
_inherit = "stock.valuation.layer"
def _get_current_user(self):
for r in self:
r.user_id = self.env.user
def _search_branch(self, operator, value):
warehouse_id= self.env['stock.warehouse'].search([('branch_id','=',self.env.user.branch_id.id)])
product_ids = self.env['product.product'].with_context(warehouse=warehouse_id.ids).search([]).filtered(lambda p:p.qty_available > 0)
return [('product_id','in',product_ids.ids)]
user = fields.Many2one('res.users', compute=_get_current_user, search=_search_branch)

You can do two things:
Put log_level = debug_sql in your Odoo configuration file. This way you will see what SQL in the logs and this will guide you to understand what with_context is doing.
If you really need to transform everything into SQL, use self.env.cr.execute("SELECT ... FROM ...") and then rows = self.env.cr.dictfetchall()

Related

AWS QLDB ion_document update

I have code that insert data into AWS QLDB using partial SQL and ion documents. Now want to update a document inside QLDB, and I can't find any example on it. Please help!
statement = 'INSERT INTO MY_TABLE'
ion_documents = loads(dumps(MY_JSON_DATA))
def query_lambda(tx_executor, query=statement, docs=ion_documents):
return tx_executor.execute_statement(query, [docs])
def retry_lambda():
print ('Retrying')
cursor = session.execute_lambda(query_lambda, retry_lambda)
As you note, you need to use PartiQL statements to update documents. The code snippet you have to insert a document is most of what you need to update it: the only change you need to make is the statement that you're executing.
The documentation has a Python tutorial which includes examples of updating documents: https://docs.aws.amazon.com/qldb/latest/developerguide/getting-started.python.step-5.html.
For example (from the above link), the following would update the owner of a vehicle in the sample application:
def update_vehicle_registration(transaction_executor, vin, document_id):
statement = "UPDATE VehicleRegistration AS r SET r.Owners.PrimaryOwner.PersonId = ? WHERE r.VIN = ?"
parameters = [document_id, convert_object_to_ion(vin)]
cursor = transaction_executor.execute_statement(statement, parameters)
try:
print_result(cursor)
logger.info('Successfully transferred vehicle with VIN: {} to new owner.'.format(vin))
except StopIteration:
raise RuntimeError('Unable to transfer vehicle, could not find registration.')
Note the use of ? as bind parameters. These will be bound to the values passed into the second argument of execute_statement (in corresponding order).
Here is some information on PartiQL update statements: https://docs.aws.amazon.com/qldb/latest/developerguide/ql-reference.update.html. The syntax is:
UPDATE table [ AS table_alias ] [ BY id_alias ]
SET element = data [, element = data, ... ]
[ WHERE condition ]
The results of running an update statement will be the document id(s) that were affected by the update.

sqlalchemy, can I get around creating the table classes?

I recently found out about sqlalchemy in Python. I'd like to use it for data science rather than website applications.
I've been reading about it and I like that you can translate the sql queries into Python.
The main thing that I am confused about that I'm doing is:
Since I'm reading data from an already well established schema, I wish I didn't have to create the corresponding models myself.
I am able to get around that reading the metadata for the table and then just querying the tables and columns.
The problem is when I want to join to other tables, this metadata reading is taking too long each time, so I'm wondering if it makes sense to pickle cache it in an object, or if there's another built in method for that.
Edit: Include code.
Noticed that the waiting time was due to an error in the loading function, rather than how to use the engine. Still leaving the code in case people comment something useful. Cheers.
The code I'm using is the following:
def reflect_engine(engine, update):
store = f'cache/meta_{engine.logging_name}.pkl'
if update or not os.path.isfile(store):
meta = alq.MetaData()
meta.reflect(bind=engine)
with open(store, "wb") as opened:
pkl.dump(meta, opened)
else:
with open(store, "r") as opened:
meta = pkl.load(opened)
return meta
def begin_session(engine):
session = alq.orm.sessionmaker(bind=engine)
return session()
Then I use the metadata object to get my queries...
def get_some_cars(engine, metadata):
session = begin_session(engine)
Cars = metadata.tables['Cars']
Makes = metadata.tables['CarManufacturers']
cars_cols = [ getattr(Cars.c, each_one) for each_one in [
'car_id',
'car_selling_status',
'car_purchased_date',
'car_purchase_price_car']] + [
Makes.c.car_manufacturer_name]
statuses = {
'selling' : ['AVAILABLE','RESERVED'],
'physical' : ['ATOURLOCATION'] }
inventory_conditions = alq.and_(
Cars.c.purchase_channel == "Inspection",
Cars.c.car_selling_status.in_( statuses['selling' ]),
Cars.c.car_physical_status.in_(statuses['physical']),)
the_query = ( session.query(*cars_cols).
join(Makes, Cars.c.car_manufacturer_id == Makes.c.car_manufacturer_id).
filter(inventory_conditions).
statement )
the_inventory = pd.read_sql(the_query, engine)
return the_inventory

Django, store function in database

I'm trying to find a way to store a function in a Django Model.
My use case is an emailer system with planned and conditional sending.
"send this email tomorrow if John has not logged in".
Ideally I would like to create emails with a test function field.
def my_test(instance):
if (now() - instance.user.last_login) > timedelta(days=1):
return False
return True
Email(send_later_date=now() + timedelta(days=1),
conditional=my_test)
Here is what I'm thinking about
import importlib
Email(send_later_date=now() + timedelta(days=1),
conditional='my_app.views.my_test')
class Email(models.Model):
send_later_date = models.DateTimeField(null=True, blank=True)
conditional = models.TextField()
def send_email(self):
if self.send_later_date < now():
if not self.conditional:
function_send_email()
else:
function_string = self.conditional
mod_name, func_name = function_string.rsplit('.',1)
mod = importlib.import_module(mod_name)
func = getattr(mod, func_name)
if func():
function_send_email()
How would you do that? I was thinking of storing the function name in a Text field. How would you run it once needed? ImportLib seems interesting...
Storing the function name is a valid aproach, since it is actually the one used by the pickle module. This has the benefit (in your case) that if you update the code of a function, it will automatically apply to existing e-mails (but be careful with backward-compatibility).
For convenience and safety (especially if the function name could come from user inputs), you may want to keep all such functions in the same module, and store only the function name in DB, not the full import path. So you could simply import the function repository and read it with getattr. I imagine you will also want to give parameters to these functions. If you don't want to restrict yourself to a given number / order / type of arguments, you could store in DB a dictionary as a JSON string, and expand it with the ** operator.
import my_app.func_store as store
import json
func = getattr(store, self.conditional)
params = json.loads(self.conditional_params)
if func(**params):
function_send_email()

Google app engine - Order listed item

I need your help to order listed item.
I am trying to make apps that can send message to his/her friends ( just like social feeds ). After watching Bret Slatkin talk about create microblogging here's my code:
class Message(ndb.Model):
content = ndb.TextProperty()
created = ndb.DateTimeProperty(auto_now=True)
class MessageIndex(ndb.Model):
receivers = ndb.StringProperty(repeated=True)
class BlogPage(Handler):
def get(self):
if self.request.cookies.get("name"):
user_loggedin = self.request.cookies.get("name")
else:
user_loggedin = None
receive = MessageIndex.query(MessageIndex.receivers == user_loggedin)
receive = receive.fetch()
message_key = [int(r.key.parent().id()) for r in receive]
messages = [Message.get_by_id(int(m)) for m in message_key]
for message in messages:
self.write(message)
The first I do a query to get all message that has my name in the receivers. MessageIndex is child of Message, then I can get key of all message that I receive. And the last is I iter get_by_id using list of message key that I get.
This works fine, but I want to filter each message by its created datetime and thats the problem. The final output is listed item, which cant be ordered using .order or .filter
Maybe some of you can light me up.
You can use the message keys in an 'IN' clause in the Message query. Note that you will need to use the parent() key value, not the id() in this case.
eg:
# dtStart, dtEnd are datetime values
message_keys = [r.key.parent() for r in receive]
query = Message.query(Message._key.IN(message_keys), Message.created>dtStart, Message.created<dtEnd)
query = query.order(Message.created) # or -Message.created for desc
messages = query.fetch()
I am unsure if you wish to simply order by the Message created date, or whether you wish to filter using the date. Both options are catered for above.

Web2Py using variables with db().count()

Ok this one should be an easy question id imagine, but cannot figure it out.
Im passing form data to the controller and attempting to do a data search there, which in turn, runs this..
def initLogin():
userName = request.vars.user_name;
counter = db(db.Users.UserName == userName).count()
if counter > 0:
return DIV("User exists")
return DIV("user does not exist")
I have checked the value is being passed correctly( which is is) by returning userName instead of the string, which shown me it was the correct value, and when i had a direct string of a correct username, it seemed to work. So my question is.. how do you run a count() function with web2py databases correctly using variables?
Your code is correct and shouldn't be giving you any problems, the only possible problem should be in your userName var not being what you expected or an incorrect sql query. I recommend that you try changing your controller to:
def initLogin():
userName = request.vars.user_name;
counter = db(db.Users.UserName == userName).count()
lastExecutedQuery = db._lastsql
return DIV( lastExecutedQuery )
And check if the query being performed is the one that you expected.

Categories

Resources