I'd like to read my Safari history database from a Julia script (Mac OS X).
I have a command line script that works:
sqlite3 -readonly ~/Library/Safari/History.db 'SELECT v.title, i.url FROM history_items i, history_visits v WHERE i.url LIKE "%en.wikipedia.org%" AND i.id=v.history_item AND v.title LIKE "%- Wikipedia%" GROUP BY v.title ORDER BY v.visit_time'
... but trying it in Julia (in Juno / Atom) gives me a permission error
db = SQLite.DB("/Users/grimxn/Library/Safari/History.db")
sql = """
SELECT v.title, i.url, v.visit_time
FROM history_items i, history_visits v
WHERE i.url LIKE "%en.wikipedia.org%"
AND i.id=v.history_item
AND v.title LIKE "%- Wikipedia%"
GROUP BY v.title
ORDER BY v.visit_time
"""
result = DBInterface.execute(db, sql) |> DataFrame
(rows, cols) = size(result)
println("Result has $(rows) rows")
println("Earliest: $(result[1,1])")
println("Latest: $(result[rows,1])")
ERROR: LoadError: SQLite.SQLiteException("unable to open database file")
Now, when I copy the database to my home directory, and swap
db = SQLite.DB("/Users/grimxn/Library/Safari/History.db")
to
db = SQLite.DB("/Users/grimxn/History.db")
everything works, so I guess it is that the Julia / Juno process has only got read permissions, but is accessing the db read/write.
How do I attach to the database as readonly in Julia?
Theoretically, use a URI connection string: file:foo.db?mode=ro.
This is documented in the SQLite manual.
Practically, it appears the current version of the SQLite.jl package does not support URIs, and neither does it support flags that could be passed along to sqlite3_open_v2().
Leaving this answer for reference just in case the Julia package fixes this some day.
Jaen's answer was correct, and also correctly predicted that the mode=ro flag would be supported. It is now supported, and so the following will work (and does as of today):
julia> using SQLite
julia> db = SQLite.DB("file:/path/to/db.sqlite?mode=ro")
SQLite.DB("file:/path/to/db.sqlite?mode=ro")
Related
my problem is, that I wrote an update, checked it in SQLiteStudio, it works fine.
When I execute the same in my program, it throws a syntax error.
('near "FROM": syntax error')
There is a difference in the sqlite3.dlls, because SQLiteStudio uses a 64bit one, my code is a 32bit Windows application, so it uses a 32bit dll. I found already some little differences (e.g. parenthesis is accepted or not) earlier in the function of the two versions, but there was always a solution to avoid the problem.
(Unfortunately I don't know any exact version number, but the 32bit version is digitally signed by Idera Inc. in 20. February 2021., it is included by Delphi 10.4 Community version.)
But this time I have no idea, what can be the problem.
The original form of my UPDATE is:
UPDATE wRoutes SET tfFeedPt = fitt.tid FROM
(SELECT wr.id AS wid, tf.id AS tid FROM wRoutes wr
JOIN xyposFitt tf
ON wr.posX = tf.posX AND wr.posY = tf.posY
AND wr.drNum = tf.drNum AND wr.page = tf.page
WHERE endpoint = "X") AS fitt
WHERE wRoutes.id = fitt.wid
It's perferct in SQLiteStudio, but throws the mentioned exception from my code.
I searched in Google a lot, and found a tip which seemed to be promising -
to use the WITH UPDATE form, so I tried this version too:
WITH fitt AS
(SELECT wr.id AS wid, tf.id AS tid FROM wRoutes wr
JOIN xyposFitt tf
ON wr.posX = tf.posX AND wr.posY = tf.posY
AND wr.drNum = tf.drNum AND wr.page = tf.page
WHERE endpoint = "X")
UPDATE wRoutes SET tfFeedPt = fitt.tid
FROM fitt
WHERE wRoutes.id = fitt.wid
It worked again in SQLiteStudio, but not in my code.
I tried the table name aliases with and without using "AS".
E.g. "FROM wRoutes wr" and "FROM wRoutes AS wr".
The result is the same: SQLiteStudio OK, my code: 'near "FROM": syntax error'.
Could somebody tell, what is wrong with my UPDATE command?
Thank you in advance.
Forpas' comment contains the correct answer:
the UPDATE...FROM syntax needs SQLite version 3.33.0+.
Upgrade of the dll to the latest (3.37.2) solved the problem.
This is my Python code (that I've checked and it works):
from warrant.aws_srp import AWSSRP
def auth(USERNAME,PASSWORD):
client = boto3.client('cognito-idp',region_name=region_name)
aws = AWSSRP(username=USERNAME, password=PASSWORD, pool_id=POOL_ID,
client_id=CLIENT_ID,client=client)
try:
tokens = aws.authenticate_user()
return(tokens)
except Exception as e:
return(e)
I'm working with R in order to create a visual interface for doing some operation (including this one) and it is a requirement.
I use the reticulare R package to execute Python code. I tested it with some dummy code in order to check the correct functioning (and it is okay).
When i execute the above function by running:
reticulate::source_python(FILE_PATH)
py$auth(USERNAME,PASSWORD)
i get the following error:
An error occurred (InvalidParameterException) when calling the RespondToAuthChallenge operation: TIMESTAMP format should be EEE MMM d HH:mm:ss z yyyy in english.
I tried to search a lot but I found nothing, I suppose that can exist a sort of wrapper or formatter. Maybe someone as already face this problem...
Thank a lot of any help.
I am discovering writing functions in TCL for Sqlite (https://github.com/pawelsalawa/sqlitestudio/wiki/ScriptingTcl).
I wanted to play a basic exemple found in the official page of sqlite(http://sqlite.org/tclsqlite.html):
db eval {SELECT * FROM MyTable ORDER BY MyID} values {
parray values
puts ""
}
I get the following error:
Error while requesting the database « -- » : invalid command name "parray"
Help is very welcome :)
SqliteStudio does not seem to fully initialise Tcl, as you would expect it from a non-embedded installation:
Using external Tcl packages or modules is not possible, because Tcl
interpreters are not initialized with "init.tcl".
See Wiki.
Background
Standard Tcl sources init.tcl, early as part of an Tcl interpreter's initialisation. init.tcl, in turn, registers a number of Tcl procs for autoloading. parray is one of those lazily acquired procs.
Ways forward
I am not familiar with SqliteStudio. Why not stick with sqlite's standard Tcl frontend, which gives you full Tcl and comes with Tcl distributions free house? But this certainly depends on your requirements.
That said, you could attempt to force-load init.tcl in SqliteStudio's embedded Tcl, but I don't know (and can't test) whether the distribution has not pruned these scripts or whether they were effectively relocated. From the top of my head (untested):
source [file join $tcl_library init.tcl]
# ...
db eval {SELECT * FROM MyTable ORDER BY MyID} values {
parray values
puts ""
}
Background: I am developing a rscript that pulls data from a mysql database, performs a logistic regression and then inserts the predictions back into the database. I want the entire system to be self contained in the script in case of database failure. This includes all mysql stored procedures that the script depends on to aggregate the data on the backend since these would be deleted in such a database failure.
Question: I'm having trouble creating a stored procedure from an R script. I am running the following:
mySQLDriver <- dbDriver("MySQL")
connect <- dbConnect(mySQLDriver, group = connection)
query <-
"
DROP PROCEDURE IF EXISTS Test.Tester;
DELIMITER //
CREATE PROCEDURE Test.Tester()
BEGIN
/***DO DATA AGGREGATION***/
END //
DELIMITER ;
"
sendQuery <- dbSendQuery(connect, query)
dbClearResult(dbListResults(connect)[[1]])
dbDisconnect(connect)
I however get the following error that seems to involve the DELIMITER change.
Error in .local(conn, statement, ...) :
could not run statement: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'DELIMITER //
CREATE PROCEDURE Test.Tester()
BEGIN
/***DO DATA AGGREGATION***/
EN' at line 2
What I've Done: I have spent quite a bit of time searching for the answer, but have come up with nothing. What am I missing?
Just wanted to follow up on this string of comments. Thank you for your thoughts on this issue. I have a couple Python scripts that need to have this functionality and I began researching the same topic for Python. I found this question that indicates the answer. The question states:
"The DELIMITER command is a MySQL shell client builtin, and it's recognized only by that program (and MySQL Query Browser). It's not necessary to use DELIMITER if you execute SQL statements directly through an API.
The purpose of DELIMITER is to help you avoid ambiguity about the termination of the CREATE FUNCTION statement, when the statement itself can contain semicolon characters. This is important in the shell client, where by default a semicolon terminates an SQL statement. You need to set the statement terminator to some other character in order to submit the body of a function (or trigger or procedure)."
Hence the following code will run in R:
mySQLDriver <- dbDriver("MySQL")
connect <- dbConnect(mySQLDriver, group = connection)
query <-
"
CREATE PROCEDURE Test.Tester()
BEGIN
/***DO DATA AGGREGATION***/
END
"
sendQuery <- dbSendQuery(connect, query)
dbClearResult(dbListResults(connect)[[1]])
dbDisconnect(connect)
I have the following SQL in a file, user.sql:
CREATE TABLE user
(
user_id INTEGER PRIMARY KEY,
username varchar(255),
password varchar(255)
);
However, when the following command is executed:
sqlite3 my.db < user.sql
The following error is generated:
Error: near line 1: near ")": syntax error
I would prefer to keep the SQL as-is, as the file will be checked into source control and will be more maintainable and readable as it is now. Can the SQL span multiple lines like this, or do I need to put it all on the same line?
I realize that this is not a direct answer to your question. As Brian mentions, this could be a silly platform issue.
If you interface with SQLite through Python, you will probably avoid most platform-specific issues and you get to have fun things like datetime columns :-)
Something like this should work fine:
import sqlite3
qry = open('create_table_user.sql', 'r').read()
conn = sqlite3.connect('/path/to/db')
c = conn.cursor()
c.execute(qry)
conn.commit()
c.close()
conn.close()
I had exactly the same problem.
Then I noticed, my editor (Notepad++) reports Macintosh format for end of lines.
Converting eols into Unix style turned the script file into format, which sqlite3 understood.
Multiple lines aren't a problem. There might be a platform issue, because I am able to run this example successfully using SQLite3 3.6.22 on OS X 10.5.8.
Here is bernie's python example upgraded to handle exceptions in the script instead of silently failing (Windows 7, ActiveState Python 3.x)
import sqlite3
import os
import os.path
import ctypes
databaseFile = '.\\SomeDB.db'
sqlFile = '.\\SomeScripts.sql'
# Delete the old table
if os.path.isfile(databaseFile):
os.remove(databaseFile)
# Create the tables
qry = open(sqlFile, 'r').read()
sqlite3.complete_statement(qry)
conn = sqlite3.connect(databaseFile)
cursor = conn.cursor()
try:
cursor.executescript(qry)
except Exception as e:
MessageBoxW = ctypes.windll.user32.MessageBoxW
errorMessage = databaseFile + ': ' + str(e)
MessageBoxW(None, errorMessage, 'Error', 0)
cursor.close()
raise