Find one - insert/update - flask_pymongo - pymongo

Here is my code:
from flask_pymongo import PyMongo
app.config['MONGO_DBNAME'] = 'TestDB'
app.config["MONGO_URI"] = "mongodb://localhost:27017/TestDB"
mongo = PyMongo(app)
filePathHash = "fhdsfl5324hfd"
score = 25
db_operations = mongo.db.sample_table
db_operations.insert({"filePathHash": filePathHash, "score": score})
As you can see, I am inserting a record and the above code works fine.
What should I do to achieve the below functionality?
Check if the record with the value of filePathHash already exists in the db. If yes then update that corresponding document, else insert it as a new record.

What you want to do is pass in the "upsert" argument:
db_operations.update({"filePathHash": filePathHash}, {"score": score}, upsert=True)

Related

Can BigQuery API overwrite existing table/view with create_table() (tables insert)?

I'm using the Python client create_table() function which calls the underlying tables insert API. There is an exists_ok parameter but this causes the function to simply ignore the create if the table already exists. The problem with this is that when creating a view, I would like to overwrite the existing view SQL if it's already there. What I'm currently doing to get around this is:
if overwrite:
bq_client.delete_table(view, not_found_ok=True)
view = bq_client.create_table(view)
What I don't like about this is there are potentially several seconds during which the view no longer exists. And if the code dies for whatever reason after the delete but before the create then the view is effectively gone.
My question: is there a way to create a table (view) such that it overwrites any existing object? Or perhaps I have to detect this situation and run some kind of update_table() (patch)?
If you want to overwrite an existing table, you can use google.cloud.bigquery.job.WriteDisposition class, please refer to official documentation.
You have three possibilities here: WRITE_APPEND, WRITE_EMPTY and WRITE_TRUNCATE. What you should use, is WRITE_TRUNCATE, which overwrites the table data.
You can see following example here:
from google.cloud import bigquery
import pandas
client = bigquery.Client()
table_id = "<YOUR_PROJECT>.<YOUR_DATASET>.<YOUR_TABLE_NAME>"
records = [
{"artist": u"Michael Jackson", "birth_year": 1958},
{"artist": u"Madonna", "birth_year": 1958},
{"artist": u"Shakira", "birth_year": 1977},
{"artist": u"Taylor Swift", "birth_year": 1989},
]
dataframe = pandas.DataFrame(
records,
columns=["artist", "birth_year"],
index=pandas.Index(
[u"Q2831", u"Q1744", u"Q34424", u"Q26876"], name="wikidata_id"
),
)
job_config = bigquery.LoadJobConfig(
schema=[
bigquery.SchemaField("artist", bigquery.enums.SqlTypeNames.STRING),
bigquery.SchemaField("wikidata_id", bigquery.enums.SqlTypeNames.STRING),
],
write_disposition="WRITE_TRUNCATE",
)
job = client.load_table_from_dataframe(
dataframe, table_id, job_config=job_config
)
job.result()
table = client.get_table(table_id)
Let me know if it suits your need. I hope it helps.
UPDATED:
You can use following Python code to update a table view using the client library:
client = bigquery.Client(project="projectName")
table_ref = client.dataset('datasetName').table('tableViewName')
table = client.get_table(table_ref)
table.view_query = "SELECT * FROM `projectName.dataset.sourceTableName`"
table = client.update_table(table, ['view_query'])
You can do it this way.
Hope this may help!
from google.cloud import bigquery
clientBQ = bigquery.Client()
def tableExists(tableID, client=clientBQ):
"""
Check if a table already exists using the tableID.
return : (Boolean)
"""
try:
table = client.get_table(tableID)
return True
except NotFound:
return False
if tableExists(viewID, client=clientBQ):
print("View already exists, Deleting the view ... ")
clientBQ .delete_table(viewID)
view = bigquery.Table(viewID)
view.view_query = "SELECT * FROM `PROJECT_ID.DATASET_NAME.TABLE_NAME`"
clientBQ.create_table(view)

ITXEX field cleared when HR_INFOTYPE_OPERATION is called

We got into difficulties in maintaining the ITXEX field (Long text indication) of an Infotype record.
Say we got an existing record in an Infotype database table with a long text filled (ITXEX field value in that record is set to 'X').
Some process updates the record through HR_CONTROL_INFTY_OPERATION like this:
CALL FUNCTION 'HR_CONTROL_INFTY_OPERATION'
EXPORTING
infty = '0081'
number = '12345678'
subtype = '01'
validityend = '31.12.9999'
validitybegin = '19.05.2019'
record = ls_0081 " ( ITXEX = 'X' )
operation = 'MOD'
tclas = 'A'
nocommit = abap_true
IMPORTING
return = ls_return.
This call does update the record but clearing it's ITXEX field.
It's important to say that making the same action through PA30 does update the record and maintain ITXEX field as it was.
The described problem seems similar to that question. Trying the solutions given there didn't solve the problem.
Why the two approaches (PA30 and function module) don't work the same? How to fix this?
First of all, FM parameters you use are incorrect. How do you want the infotype to be updated if you set nocommit = TRUE?
Also, you are missing the correct sequence which must be used for the update procedure:
Lock the Employee
Read the infotype
Update the infotype
Unlock the Employee
The correct snippet for your task would be
DATA: ls_return TYPE bapireturn1.
DATA: l_infty_tab TYPE TABLE OF p0002.
CALL FUNCTION 'HR_READ_INFOTYPE'
EXPORTING
pernr = '00000302'
infty = '0002'
TABLES
infty_tab = l_infty_tab.
READ TABLE l_infty_tab ASSIGNING FIELD-SYMBOL(<infotype>) INDEX 1.
<infotype>-midnm = 'Shicklgruber'. " updating the field of infotype
CALL FUNCTION 'ENQUEUE_EPPRELE'
EXPORTING
pernr = '00000302'
infty = '0002'.
CALL FUNCTION 'HR_CONTROL_INFTY_OPERATION'
EXPORTING
infty = <infotype>-infty
number = <infotype>-pernr
subtype = <infotype>-subty
validityend = <infotype>-endda
validitybegin = <infotype>-begda
record = <infotype>
operation = 'MOD'
tclas = 'A'
IMPORTING
return = ls_return.
CALL FUNCTION 'DEQUEUE_EPPRELE'
EXPORTING
pernr = '00000302'
infty = '0002'.
This way itxex field is treated correctly and if existed on that record, will remain intact. However, this method will not work for updating the long text itself, for that you must use object-oriented way, methods of class CL_HRPA_INFOTYPE_CONTAINER.

Update a Table using a Join

I wish to update a table using, but need to use another table to get the correct field. The new information is not taken from another field from another table.
The following SQL statement returns the correct information:
SELECT PURCHASEHEADER.ORDERNOTES
FROM PURCHASEHEADER, ASSEMBLYLINESOURCE
WHERE ASSEMBLYLINESOURCE.HEADERSYSUNIQUEID = 72637001
AND PURCHASEHEADER.ORDERNUMBER = ASSEMBLYLINESOURCE.PURCHASEORDERNUMBER
I have tried the following:
UPDATE PURCHASEHEADER SET PURCHASEHEADER.ORDERNOTES = 'Updated'
WHERE EXISTS (
SELECT 1 FROM ASSEMBLYLINESOURCE
WHERE PURCHASEHEADER.ORDERNUMBER = ASSEMBLYLINESOURCE.PURCHASEORDERNUMBER
) AND ASSEMBLYLINESOURCE.HEADERSYSUNIQUEID = 72637001
An error is returned saying: " ...Column Unknown ASSEMBLYLINESOURCE.HEADERSYSUNIQUEID..." but it does exist as it works in the first query.
I have seen similar posts from Mark Rotteveel dated July 2017, but still can't get it to work.
There is an issue with your closing bracket. Try this, it worked for me.
UPDATE PURCHASEHEADER set PURCHASEHEADER.ORDERNOTES = 'Updated'
WHERE EXISTS (SELECT 1 FROM ASSEMBLYLINESOURCE WHERE
PURCHASEHEADER.ORDERNUMBER = ASSEMBLYLINESOURCE.PURCHASEORDERNUMBER AND
ASSEMBLYLINESOURCE.HEADERSYSUNIQUEID = 72637001)

How to use If statement in addCondition, YII

I have some conditions to hand on to my dataprovider. Now, my last condition I want only to take place only when the field "edit" is set to true -> In this case I want to check if the editConfirmed field 'editBevestigd' is set to true. If the 'edit' field is empty I don't want to add this last condition.
$criteria->addCondition('bevestigd = 1');
$criteria->addCondition('IF(edit = 1) editBevestigd = 1');
What is the best way to handle this. Can I do this in YII (problem here is that the record is not known yet). Or how do I write this in SQL (I know this last condition isn't right right now..)?
Thanks in advance!
If i right understand what you want then you should use this condition:
WHERE (edit = 1 AND editBevestigd = 1) OR edit = 0
Thus, the condition becomes:
$criteria->addCondition('(edit = 1 AND editBevestigd = 1) OR edit = 0');
You can try like that
//for php variable set or not
if($edit==1){
$criteria->addCondition('editBevestigd=1');
}
//for column set or not
$criteria->addCondition('edit IS NOT NULL AND editBevestigd=1');

Corona Lua SQLite

this is my first question on stackOverflow.
I'm working with Corona and I'm having an issue accessing a SQLdb (I'm a bit of a SQL noob.)
I'm trying to access and return a value I've stored in the database.
Here's some code samples:
print("---------------- How I Create New Player Save Data")
local entry = [[CREATE TABLE IF NOT EXISTS playerData (key STRING PRIMARY KEY, content INTEGER);]]
db:exec(entry)
entry = [[INSERT INTO playerData VALUES ("LastLoginTime", 0);]]
db:exec( entry )
entry = [[INSERT INTO playerData VALUES ("Credits", 1000);]]
db:exec( entry )
entry = [[INSERT INTO playerData VALUES ("Level", 1);]]
db:exec( entry )
Now this function works, it will print everything in the db (i pass in 'dbName'):
--print all the table contents
for row in db:nrows("SELECT * FROM "..dbName) do
local text = row.key..": "..row.content
end
This doesn't work, it returns '0':
local grabCredits = "SELECT content FROM playerData WHERE key='Credits'"
local credits = db:exec(grabCredits)
print("-- value: "..credits)
Neither does this, also returns '0':
local grabCredits = "SELECT key FROM playerData WHERE content>=10"
local credits = db:exec(grabCredits)
print("-- value: "..credits)
I don't understand what I'm doing wrong. Maybe I need to use another function call on the db other than exec(). I realize I could iterate through the db every time I want to access a single entry, but that just seems inefficient.
Any help is very much appreciated.
If you want results, you must use some form of iterator. SQLite always returns rows for a query result.
This is similar to what I'm using to retrieve one result from my database and works well for me.
local query = "SELECT content FROM playerData WHERE key = 'Credits' LIMIT 1"
local queryResultTable = {}
local queryFunction = function(userData, numberOfColumns, columnValues, columnTitles)
for i = 1, numberOfColumns do
queryResultTable[columnTitles[i]] = columnValues[i]
end
end
db:exec(query, queryFunction)
for k,v in pairs(queryResultTable) do
print(k,v)
end