I like to keep one file with just my f strings that represents SQL queries and each query needs a db name. In my python program, i will populate the db variable as I am reading out db names.
E.g.
in queries.py, i have
query_1 = f"select * from {db} limit 10;"
in main.py, i use
from quries import quries
# read out db information into dbs
for db in dbs:
# execute the query_1 for each db
How can I achieve the logic in the loop?
Don't use an f-string, but .format()
# queries
query_1 = "select * from {db} limit 10;"
from queries import query_1
...
for db in dbs:
query = query_1.format(db=db)
...
Related
I am using sqlite3 with python, and after connecting to the database and creating a table, sqlite3 shows an error when I try to execute a SELECT statment on the table with the name of the databse in it :
con = sqlite3.connect("my_databse")
cur = con.cursor()
cur.execute('''CREATE TABLE my_table ... ''')
cur.execute("SELECT * FROM my_database.my_table") # this works fine without the name of the database before the table name
but I get this error from sqlite3 :
no such table : my_database.my_table
Is there a way to do a SELECT statment with the name of the database in it ?
The short answer is no you can't do this with SQLite. This is because you already specify the database name with sqlite3.connect() and SQLite3 doesn't allow multiple databases in the same file.
Make sure of the database is in the same directory with the python script. In order to verify this you can use os library and os.listdir() method. After connecting the database and creating the cursor, you can query with the table name.
cur.execute('SELECT * FROM my_table')
Currently i'm executing stored procedure that way:
engine = sqlalchemy.create_engine(self.getSql_conn_url())
query = "exec sp_getVariablesList #City = '{0}', #Station='{1}'".format(City, Station)
self.Variables = pd.read_sql_query(query, engine)
but at How set ARITHABORT ON at sqlalchemy was correctly noticed that that make that open to SQL injection. I tried different ways but without success. So how should I pass parameters to the MSSQL stored procedure to eliminate the risk of SQL injection? That can be with sqlalchemy or any other way.
Write your SQL command text using the "named" paramstyle, wrap it in a SQLAlchemy text() object, and pass the parameter values as a dict:
import pandas as pd
import sqlalchemy as sa
connection_uri = "mssql+pyodbc://#mssqlLocal64"
engine = sa.create_engine(connection_uri)
# SQL command text using "named" paramstyle
sql = """
SET NOCOUNT ON;
SET ARITHABORT ON;
EXEC dbo.breakfast #name = :name_param, #food = :food_param;
"""
# parameter values
param_values = {"name_param": "Gord", "food_param": "bacon"}
# execute query wrapped in SQLAlchemy text() object
df = pd.read_sql_query(sa.text(sql), engine, params=param_values)
print(df)
"""
column1
0 Gord likes bacon for breakfast.
"""
I have a basic question here. I am pulling a SQL output as below:
cur = connection.cursor()
cur.execute("""select store_name,count(*) from stores group by store_name""")
data = cur.fetchall()
The output of the above SQL is as below:
Store_1,23
Store_2,13
Store_3,43
Store_4,2
I am trying to read column 1 (store_name) in the above output.
Expected Output:
Store_1
Store_2
Store_3
Store_4
Could anyone advice on how could I have this done. Thanks..
If I correctly understand your question, I guess just correcting your SQL will give you the desired result. Fetch distinct store_name
select distinct store_name from stores
Edit
Response to comment:
Try following:
from operator import itemgetter
data = cur.fetchall()
list(map(itemgetter(0), data)) # your answer
In your code, you can simply append the following lines:
for rows in data:
print(rows[0])
hope this helps.
BTW: I am not on the computer and have not crosschecked the solution.
Harvard's CS50 web class has the following which I think helps you in it's last 3 lines.
import os
from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session, sessionmaker
engine = create_engine(os.getenv("DATABASE_URL")) # database engine object from SQLAlchemy that manages connections to the database
# DATABASE_URL is an environment variable that indicates where the database lives
db = scoped_session(sessionmaker(bind=engine)) # create a 'scoped session' that ensures different users' interactions with the
# database are kept separate
flights = db.execute("SELECT origin, destination, duration FROM flights").fetchall() # execute this SQL command and return all of the results
for flight in flights
print(f"{flight.origin} to {flight.destination}, {flight.duration} minutes.") # for every flight, print out the flight info
So in your case I suppose its:
results = db.execute( <PUT YOUR SQL QUERY HERE> )
for row in results:
print(row.store_name)
I would like to connect to MS SQL Server and execute a SQL command with python. I am familiar with using SQLAlchemy to create SQL tables, pandas DataFrames, etc., but how can I execute the SQL in a .sql file with python/pandas/SQLAlchemy? Is there a better way to do it?
For example I have the file 'update.sql' that contains the SQL text:
truncate table dev.dbo.jobs
truncate table dev.dbo.workers
go
insert into dev.dbo.jobs select * from test.dbo.jobs
insert into dev.dbo.workers select * from test.dbo.workers
You can use SQLAlchemy's connection.execute to run raw SQL queries. If you have the sql statements stored in a file then it might look something like this:
from sqlalchemy import create_engine
from sqlalchemy.sql import text
engine = create_engine('urltodb')
conn = engine.connect()
with open('file.sql', 'r') as f:
for l in f:
stmt = text(l)
conn.execute(stmt)
conn.close()
I'm trying to execute some raw SQL against a temp table through the web2py DAL, but my results are all returning None.
Here's the full function:
def test():
db_test = DAL('mysql://root:root#localhost/test')
sql = """CREATE TEMPORARY TABLE tmp LIKE people;
INSERT INTO tmp SELECT * FROM people;
INSERT INTO tmp SELECT * FROM people;
SELECT * FROM tmp;"""
results = db_test.executesql(sql)
Obviously the SQL is a simplification, but running the same SQL in a SQL pane returns the correct results. What do I need to do to get the DAL working with this?
You cannot execute multiple statements in one executesql call I suspect; web2py uses the DBAPI 2.0 .execute() call for sending these to the backend database and that usually supports only single statements:
db_test = DAL('mysql://root:root#localhost/test')
sqlddl = """CREATE TEMPORARY TABLE tmp LIKE people;
INSERT INTO tmp SELECT * FROM people;
INSERT INTO tmp SELECT * FROM people;"""
for statement in sqlddl.split(';'):
db_test.executesql(statement.strip())
sqlselect = "SELECT * FROM tmp;"
results = db_test.executesql(sqlselect)