access error in xlsx report from odoo - report

The access rule in multi company. The user's allowed company is 1 company.
Print custom report action, then error is:
Please contact your system administrator( sale.order, Operation: read)
The report is xlsx report. The query is:
def _get_values(self, date_from, date_to, company_id):
self.env.cr.execute("""(
Select
//some field
FROM ( sale_order s
join sale_order_line l on (l.order_id=s.id)
join res_partner partner on s.partner_id = partner.id
left join product_product p on (l.product_id=p.id)
left join product_template t on (p.product_tmpl_id=t.id)
left join stock_warehouse w on (w.id=s.warehouse_id)
)
WHERE s.date_order >= '%s' AND s.date_order < '%s' AND s.company_id IN %s
GROUP BY fields
ORDER BY s.date_order) """
% (date_from.strftime('%Y-%m-%d %H:%M:%S'), date_to.strftime('%Y-%m-%d %H:%M:%S'), tuple( company_id)))
return self.env.cr.fetchall()
How to fix this access error. Help, I need any solution and advice. Thanks for your help!
Additional note:
def generate_xlsx_report(self, workbook, data, lines):
lines = self._get_values(date_from, date_to, aa)
for line in lines:
sheet.write(rowx, 1, line[0], format_datetime)
// some write sheet ...
and print button action in call xlsx report.
The code is:
#api.multi
def export_xls(self):
datas = {'date_from': self.date_from,
'date_to': self.date_to}
return {'type': 'ir.actions.report.xml',
'report_name': 'sale_report.xlsx',
'datas': datas,
'name': _('Sales report excel')
}
Comment: it works just fine with many companies

Related

How to error check a function containing a SQL query with the placeholder %s

I am working on a project for school and run into a crossroad. I have a bunch of queries in a python script that a user can search when running the script. A couple of these function are using %s as a placeholder so that the user can enter a value.
However, I want to check that what they enter is actually in my database. For instance, if you ask a user for a movie genre, it should produce an error if they enter something that is not in my tables.
I have spent a few days trying to find a way to do it, with no luck. I am not the greatest with functions, and I get things mixed up some times.
To simplify things I copied one of my queries requiring user input for testing. I thought I had come up with a solution on how to error check, but no luck. I have pasted the code below. If you know what I am missing, your help would be much appreciated.
#!/usr/bin/python36
#Modules
############################
import psycopg2
import sys
import os
#Open Database
############################
global cursor
#def OpenDatabase():
try:
connection = psycopg2.connect(database='Blockbuster36', user='dbadmin')
cursor = connection.cursor()
except psycopg2.DatabaseError:
print("No connection to database.")
sys.exit(1)
#Functions
###########################
def Show_Tuples():
tuple = cursor.fetchone()
while tuple != None:
print(tuple)
tuple = cursor.fetchone()
#3) Display all films of a certain genre
def Qry3_Film_of_Genre(Genre_Choice):
Qry3 = '''select Film_Title, Genre_Name from Film
join Film_Genre
on Film.Film_ID = Film_Genre.Film_ID
join Genre
on Film_Genre.Genre_ID = Genre.Genre_ID
where Genre_Name = %s;'''
cursor.execute(Qry3, (Genre_Choice,))
Show_Tuples()
def Qry3_Error_Check(Genre_Choice):
try:
Qry3_ec = "select Genre_ID, Genre_Name from Genre where Genre_Name = %s;"
cursor.execute(Qry3_ec, (Genre_Choice,))
results = cursor.fetchone()
if results[0] > 0:
print()
Qry3_Film_of_Genre(Genre_Choice)
# else:
elif results[0] == None:
print("This Genre does not exist")
Genre_Choice = input("Please enter the Genre name to filter movies by: ")
except psycopg2.Error as query_issue:
print("Something wrong with the query", query_issue)
except Exception as unkown:
print("Error: Something else went wrong")
print("Here is the issue: ", unkown)
#Main Code
##########################
Genre_Choice = input("Please enter the Genre name to filter movies by: ")
Check_Genre = Qry3_Error_Check(Genre_Choice)
#print("Function Return: ", Check_Genre)
#print()
#print(Check_Genre)
#if Check_Genre == None:
# print("This Genre does not exist")
# Genre_Choice = input("Please enter the Genre name to filter movies by: ")
# Check_Genre = Qry3_Error_Check(Genre_Choice)
#elif Check_Genre != None:
# Qry3_Film_of_Genre(Genre_Choice)
#while Check_Genre != Genre_Choice:
# print("This Genre does not exist")
# Genre_Choice = input("Please enter the Genre name to filter movies by: ")
# Check_Genre = Qry3_Error_Check(Genre_Choice)
#if Check_Genre == None:
# Qry3_Film_of_Genre(Genre_Choice)
#Close Cursor and Database
###################################
cursor.close()
connection.close()
Essentially I want the error message to keep printing, along with entering another genre name, until a valid genre is entered. Right now it keeps saying it is wrong even if enter a valid genre name and get output with the Qry3_Error_Check function.
Once the user has entered a valid genre name, based on the error-checking function query, then the original query will appear.
I have made some progress, entering a valid genre now works. However, when entering an invalid genre name it jumps to the general except and prints the error "NoneType object is not subscriptable." Obviously, there are no rows that match, thus the NoneType error. However, it should re-prompt the user in the elif statement above. What do enter as an elif statement so that the user is re-prompted for a valid genre name?
Note: I commented out the bulk of my main code for now.
If you want to check specifically for SQL errors, you can have a separate except block for them. Also, its usually (but not always) a bad idea to use exceptions for control flow.
Something like below (I have not tested this) is probably close to what you need.
try:
Qry3_ec = "select Genre_ID, Genre_Name from Genre where Genre_Name = %s;"
cursor.execute(Qry3_ec, (Genre_Choice,))
results = cursor.fetchall()
if results.count > 0:
print(results)
else:
print("Nothing found!")
except psycopg2.Error as e:
print("Something wrong with the query")
print(e)
except Exception as e
print("Something else went wrong")
print(e)
Good luck with your project. :)

Query is unable to match parts after "/" or parts within "()" in the data

I have a search request written as
import sqlite3
conn = sqlite3.connect('locker_data.db')
c = conn.cursor()
def search1(teacher):
test = 'SELECT Name FROM locker_data WHERE Name or Email LIKE "%{0}%"'.format(teacher)
data1 = c.execute(test)
return data1
def display1(data1):
Display1 = []
for Name in data1:
temp1 = str(Name[0])
Display1.append("Name: {0}".format(temp1))
return Display1
def locker_searcher(teacher):
data = display1(search1(teacher))
return data
This allows me to search for the row containing "Mr FishyPower (Mr Swag)" or "Mr FishyPower / Mr Swag" with a search input of "FishyPower". However, when I try searching with an input of "Swag", I am then unable to find the same row.
In the search below, it should have given me the same search results.
The database is just a simple 1x1 sqlite3 database containing 'FishyPower / Mr Swag'
Search Error on 'Swag'
Edit: I technically did solve it by limiting the columns being searched to only 'Name' but I intended the code search both the 'Name' and 'Email' columns and output the results as long as the search in within either or both columns.
Edit2: SELECT Name FROM locker_data WHERE Email LIKE "%{0}%" or Name LIKE "%{0}%" was the right way to go.
I'm gonna guess that Mr. FishyPower's email address is something like mrFishyPower#something.com. The query is only comparing Email to teacher. If it was
WHERE Name LIKE "%{0}%"
OR Email LIKE "%{0}%"'
you would (probably) get the result you want.

Airflow: How to push xcom value from BigQueryOperator?

This is my operator:
bigquery_check_op = BigQueryOperator(
task_id='bigquery_check',
bql=SQL_QUERY,
use_legacy_sql = False,
bigquery_conn_id=CONNECTION_ID,
trigger_rule='all_success',
xcom_push=True,
dag=dag
)
When I check the Render page in the UI. Nothing appears there.
When I run the SQL in the console it return value 1400 which is correct.
Why the operator doesn't push the XCOM?
I can't use BigQueryValueCheckOperator. This operator is designed to FAIL against a check of value. I don't want nothing to fail. I simply want to branch the code based on the return value from the query.
Here is how you might be able to accomplish this with the BigQueryHook and the BranchPythonOperator:
from airflow.operators.python_operator import BranchPythonOperator
from airflow.contrib.hooks import BigQueryHook
def big_query_check(**context):
sql = context['templates_dict']['sql']
bq = BigQueryHook(bigquery_conn_id='default_gcp_connection_id',
use_legacy_sql=False)
conn = bq.get_conn()
cursor = conn.cursor()
results = cursor.execute(sql)
# Do something with results, return task_id to branch to
if results == 0:
return "task_a"
else:
return "task_b"
sql = "SELECT COUNT(*) FROM sales"
branching = BranchPythonOperator(
task_id='branching',
python_callable=big_query_check,
provide_context= True,
templates_dict = {"sql": sql}
dag=dag,
)
First we create a python callable that we can use to execute the query and select which task_id to branch too. Second, we create the BranchPythonOperator.
The simplest answer is because xcom_push is not one of the params in BigQueryOperator nor BaseOperator nor LoggingMixin.
The BigQueryGetDataOperator does return (and thus push) some data but it works by table and column name. You could chain this behavior by making the query you run output to a uniquely named table (maybe use {{ds_nodash}} in the name), and then use the table as a source for this operator, and then you can branch with the BranchPythonOperator.
You might instead try to use the BigQueryHook's get_conn().cursor() to run the query and work with some data inside the BranchPythonOperator.
Elsewhere we chatted and came up with something along the lines of this for putting in the callable of a BranchPythonOperator:
cursor = BigQueryHook(bigquery_conn_id='connection_name').get_conn().cursor()
# one of these two:
cursor.execute(SQL_QUERY) # if non-legacy
cursor.job_id = cursor.run_query(bql=SQL_QUERY, use_legacy_sql=False) # if legacy
result=cursor.fetchone()
return "task_one" if result[0] is 1400 else "task_two" # depends on results format

Multiple commits to neo4j from R

I have collected some tweets using the twitteR package and thereafter exported them to a neo4j database using Nicole White's various tutorials. I extract the tweets to a dataframe called kdf and thereafter use functions from stringr for basic cleaning up as demonstrated by Nicole. I am then sending this to neo4j from R. The essential part of my code is:
library(RNeo4j)
graph = startGraph("http://localhost:7474/db/data/", username="xxxx", password="xxxx")
clear(graph)
addConstraint(graph, "Tweet", "id")
addConstraint(graph, "User", "username")
addConstraint(graph, "Hashtag", "hashtag")
addConstraint(graph, "Tags", "ent_tag")
query = "
CREATE (tweet:Tweet {id: {tweetID}})
SET tweet.text = {text}
CREATE (user:User {name: {Username}})
CREATE (user)-[:TWEETED]->(tweet)
FOREACH(reply_to_sn IN CASE {reply_to_sn} WHEN NULL then [] else [{reply_to_sn}] END |
MERGE (replytouser:User {username:{reply_to_sn}})
CREATE (tweet)-[:IN_REPLY_TO]->(replytouser)
)
FOREACH(retweet_sn IN CASE {retweet_sn} WHEN NULL THEN [] ELSE [{retweet_sn}] END |
MERGE(retweet_user:User {username: {retweet_sn}})
CREATE (tweet)-[:RETWEET_OF]->(retweet_user)
)
FOREACH(hastag_nodes IN CASE {hashtag_nodes} WHEN NULL then [] else [{hashtag_nodes}] END |
MERGE (h:Hashtag {hashtag :{hashtag_nodes}})
CREATE (tweet)-[:HASHTAG]->(h)
)
FOREACH(mentioned_users IN CASE {mentioned_users} WHEN NULL then [] else [{mentioned_users}] END |
MERGE (m:User {username :{mentioned_users}})
CREATE (tweet)-[:MENTIONED]->(m)
)
"
tx = newTransaction(graph)
for(i in 1:nrow(kdf)){
row = kdf[i, ]
appendCypher(tx, query,
tweetID=row$id,
text=row$text,
Username=row$screenName,
reply_to_sn=row$replyToSN,
retweet_sn=getRetweetSN(row$text),
hashtag_nodes=getHashtags(row$text),
mentioned_users=getMentions(row$text))
}
commit(tx)
What I have done thereafter is extracted named entities for all the text using Watson's Alchemy API. This is stored in a dataframe called ent_tbl. This contains three variables, tweetid, etext and etype. Now I am trying to export this data too to the same neo4j databse and join on the id of the tweets. This is the other part of the code:
query="
MATCH(t:ent_tag {id : $twid, type :$etype, text :$etext})
MATCH(tw:tweet {tweetID : $twid })
CREATE (tw)-[:HAS_ENT]->(t)
"
tx=newTransaction(graph)
for (i in 1:nrow(ent_tbl)){
row = ent_tbl[i,]
appendCypher(tx, query,
twid=row2$tweetid,
etype=row2$etype,
etext=row2$etext)
}
commit(tx)
While I do not get any errors on committing this, summary(graph) does not show me the relationship between the tags (t) and the tweets (tw) that I expected to see.
> summary(graph)
This To That
1 User TWEETED Tweet
2 Tweet RETWEET_OF User
3 Tweet HASHTAG Hashtag
4 Tweet MENTIONED User
5 Tweet IN_REPLY_TO User
Why would this happen?
This is my db.schema in neo4j:
That is because the MATCH does not find any tag or tweet so it breaks. If you want to add data to existing nodes, you should match them by ID and then set their properties. And you got to be consistent with labels and upper/lower cases. I think this is what you are looking for.
query="
MATCH(t:Tags {ent_tag : $twid})
MATCH(tw:Tweet {tweetID : $twid })
SET t.type=$etype, t.text=$etext
CREATE (tw)-[:HAS_ENT]->(t)
"
tx=newTransaction(graph)
for (i in 1:nrow(ent_tbl)){
row = ent_tbl[i,]
appendCypher(tx, query,
twid=row2$tweetid,
etype=row2$etype,
etext=row2$etext)
}
commit(tx)

writing to and reading peewee

I am writing a program that scrapes tweets of a number of people, if the body of the tweet is unique it will get stored in the sqlite database for that person. I have two files, one to write to the databases and one to read the database for and search for tweets with a search word. Before writing to databases I printed the tweets on the terminal, the tweets are being pulled from twitter correctly. When I try a search a term all databases have zero tweets, even if there is no term. There is either a problem with the writing or reading of the database. Please help, I appreciate that I am very new to python.
the writing file:
import requests
import datetime
from bs4 import BeautifulSoup
from peewee import *
from time import sleep
databases = ["femfreq.db", "boris_johnson.db", "barack_obama.db",
"daily_mail.db", "guardian.db", "times.db", "zac_goldsmith.db",
"bernie_sanders.db", "george_osborne.db", "john_mcdonnell.db",
"donald_trump.db", "hillary_clinton.db", "nigel_farage.db"]
urls = ["https://twitter.com/femfreq", "https://twitter.com/BorisJohnson",
"https://twitter.com/BarackObama",
"https://twitter.com/MailOnline?ref_src=twsrc%5Egoogle%7Ctwcamp%5Eserp%7Ctwgr%5Eauthor",
"https://twitter.com/guardian?ref_src=twsrc%5Egoogle%7Ctwcamp%5Eserp%7Ctwgr%5Eauthor",
"https://twitter.com/thetimes",
"https://twitter.com/ZacGoldsmith?ref_src=twsrc%5Egoogle%7Ctwcamp%5Eserp%7Ctwgr%5Eauthor",
"https://twitter.com/berniesanders?lang=en-gb",
"https://twitter.com/George_Osborne?ref_src=twsrc%5Egoogle%7Ctwcamp%5Eserp%7Ctwgr%5Eauthor",
"https://twitter.com/johnmcdonnellMP?ref_src=twsrc%5Egoogle%7Ctwcamp%5Eserp%7Ctwgr%5Eauthor",
"https://twitter.com/realDonaldTrump?ref_src=twsrc%5Egoogle%7Ctwcamp%5Eserp%7Ctwgr%5Eauthor",
"https://twitter.com/HillaryClinton?ref_src=twsrc%5Egoogle%7Ctwcamp%5Eserp%7Ctwgr%5Eauthor"
"https://twitter.com/Nigel_Farage?ref_src=twsrc%5Egoogle%7Ctwcamp%5Eserp%7Ctwgr%5Eauthor"]
selection = 0
for database_chosen in databases:
r = requests.get(urls[selection])
soup = BeautifulSoup(r.content, "html.parser")
content =soup.find_all("div",
{"class":
"content"})
db = SqliteDatabase(database_chosen)
class data_input(Model):
time_position = DateTimeField(default=datetime.datetime.now)
header = CharField()
time_posted = CharField()
tweet_body = CharField(unique=True)
class Meta:
database = db
db.connect()
db.create_tables([data_input], safe=True)
for i in content:
try:
data_input.create(header = i.contents[1].text,
time_posted = i.contents[3].text,
tweet_body = i.contents[5].text)
except IntegrityError:
pass
for i in content:
print("=============")
print(i.contents[1].text)
print(i.contents[3].text)
print(i.contents[5].text)
selection += 1
print("database: {} updated".format(database_chosen))
For the reading file
from peewee import *
import datetime
databases = ["femfreq.db", "boris_johnson.db", "barack_obama.db",
"daily_mail.db", "guardian.db", "times.db", "zac_goldsmith.db",
"bernie_sanders.db", "george_osborne.db", "john_mcdonnell.db",
"donald_trump.db", "hillary_clinton.db", "nigel_farage.db"]
search_results = []
search_index = 0
print("")
print("Please enter the number for the database you want to search: ")
for i in databases:
print("{}:{}".format(i, search_index))
search_index += 1
select = int(input("please select: "))
database_chosen = databases[select]
db = SqliteDatabase(database_chosen)
class data_input(Model):
time_position = DateTimeField(default=datetime.datetime.now)
header = CharField()
time_posted = CharField()
tweet_body = CharField(unique=True)
class Meta:
database = db
db.connect()
enteries = data_input.select().order_by(data_input.time_position.desc())
print(enteries)
enteries = enteries.where(data_input.tweet_body)
print("")
print("The total number of tweets in {} is: {}".format(database_chosen,
len(enteries)))
For the reading file I haven't put in a search function yet I will move to that when I can get this problem first. Many thanks
What are you intending to accomplish by putting ".where(data_input.tweet_body)" in the query to read entries? Try removing that whole line:
entries = entries.where(data_input.tweet_body)
When you go to add your search, at that time you will want to add a where clause...something like:
entries = entries.where(data_input.tweet_body.contains(search_term))

Resources