Is there any way to execute some SQL commands in .sql file from within Python, but not all SQL commands in the file? Suppose I have the following .sql
file:
DROP TABLE IF EXISTS `tableA`;
CREATE TABLE `tableA`(
some_code
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
DROP TABLE IF EXISTS `tableB`;
CREATE TABLE `tableB`(
some_code
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
DROP TABLE IF EXISTS `tableC`;
CREATE TABLE `tableC`(
some_code
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
...to be continued...
In this file, I want to parse and run only tableB
-related command (i.e. drop and create tableB
), but don't like to execute any SQL commands on other tables from within Python. I have some knowledge on how to execute .sql file from within Python, but don't know how to execute only some specific commands in .sql file as stated in the above example. The first thing striking upon my head is to use regular expression. But after a little bit of wrangling, I couldn't come up with the correct regex syntax to get me what I expected due to my poor regex knowledge and experience.
So my question is,
1) Is it the correct way here to use regular expression to get only the desired commands, and if so, can you show me the correct syntax to parse it?
2) If regular expression is not the best way here, what is an alternative solution?
3) I found some online regex testing tools, but all of them is to specify both the expression and test strings, and highlight matched data in the string. I believe it's great if there are some tools that have me specify test strings first, then highlight the desired data within the string manually, and then returns some appropriate syntax/expression adversely. If you know such tools (no restriction to online tools! I'm also glad if it's Macintosh Application), please tell me...
Thanks.
But Python is still passing the SQL st You have a set of static queries in a SQL file that you want executed via a python script You have a set of dynamic queries that you want to define and execute via a python script
TwoLaid's Python SQL Parser works very well for my purposes. It's written in C and needs to be compiled. It is robust. It parses out individual elements of each clause. I'm using it to parse out queries column names to use in report headers. Here is an example.
The answer depends on that database you are using. Typically the people who made the database system will provide a Python binding. This is the sort of question that isn’t even quite wrong. There isn’t a standard way to “run a .sql file” in any system. But, in any case, you’re never running SQL “in” Python.
I implemented a simple SQL parser using pyparsing. Combined with Python code that implement the relational operations against my data store, this was fairly simple. As I said in one of the comments, the point of the exercise was to make the data available to reporting engines. To do this, I probably will need to implement an ODBC driver.
You can try out the sqlparse library that will ease your work by parsing SQL statements and give you the capapbility to query and work with tokens within a SQL statement. It can be a goos base to filter out statements containing a specific token like tableB
in your case
While regex may not be the right tool, you can still use it.
>>> statements = """
... DROP TABLE IF EXISTS `tableA`;
...
... CREATE TABLE `tableA`(
... some_code
... ) ENGINE=MyISAM DEFAULT CHARSET=latin1;
...
... DROP TABLE IF EXISTS `tableB`;
...
... CREATE TABLE `tableB`(
... some_code
... ) ENGINE=MyISAM DEFAULT CHARSET=latin1;
...
... DROP TABLE IF EXISTS `tableC`;
...
... CREATE TABLE `tableC`(
... some_code
... ) ENGINE=MyISAM DEFAULT CHARSET=latin1;
... """
>>> regex = r"((?:CREATE|DROP) TABLE (?:IF (?:NOT )?EXISTS )?`tableB`(?:[^;]|(?:'.*?'))*;)"
>>> re.findall(regex, statements, re.I)
['DROP TABLE IF EXISTS `tableB`;', 'CREATE TABLE `tableB`(\nsome_code\n) ENGINE=MyISAM DEFAULT CHARSET=latin1;']
>>>
If you are wondering what
`(?:[^;]|(?:'.*?'))*`
is for, it is simply used to match any character except ;
, any amount of times, including none
or
a string literal, meaning it will allow ;
to match inside a string like 'this is a ;value; for a varchar field'
.
Although I personally believe you should use some parsing library to parse an AST of the SQL, looking through the code makes this option viable too:
my_sql_code = '''DROP TABLE...''' #big long string, multiline
statements = my_sql_code.split(';')
statements = [s for s in statements if 'tableB' in s]
for s in statements:
execute_sql(s)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With