【问题标题】:reading external sql script in python在python中读取外部sql脚本
【发布时间】:2013-10-28 16:05:10
【问题描述】:

我正在学习如何在 python 中执行 SQL(我知道 SQL,而不是 Python)。

我有一个外部 sql 文件。它创建数据并将数据插入到三个表“Zookeeper”、“Handles”、“Animal”中。

然后我有一系列查询要运行表。以下查询位于我在 python 脚本顶部加载的 zookeeper.sql 文件中。前两个的例子是:

--1.1

SELECT ANAME,zookeepid
FROM ANIMAL, HANDLES
WHERE AID=ANIMALID;

--1.2

SELECT ZNAME, SUM(TIMETOFEED)
FROM ZOOKEEPER, ANIMAL, HANDLES
WHERE AID=ANIMALID AND ZOOKEEPID=ZID
GROUP BY zookeeper.zname;

这些都在 SQL 中执行得很好。现在我需要从 Python 中执行它们。我已经获得并完成了读取文件的代码。然后执行循环中的所有查询。

1.1 和 1.2 是我感到困惑的地方。我相信在循环中,这是我应该放入一些东西来运行第一个和第二个查询的行。

result = c.execute("SELECT * FROM %s;" % table);

但是什么?我想我错过了一些非常明显的东西。我认为让我失望的是 % table。在查询 1.1 和 1.2 中,我不是在创建表,而是在查找查询结果。

我的整个python代码如下。

import sqlite3
from sqlite3 import OperationalError

conn = sqlite3.connect('csc455_HW3.db')
c = conn.cursor()

# Open and read the file as a single buffer
fd = open('ZooDatabase.sql', 'r')
sqlFile = fd.read()
fd.close()

# all SQL commands (split on ';')
sqlCommands = sqlFile.split(';')

# Execute every command from the input file
for command in sqlCommands:
    # This will skip and report errors
    # For example, if the tables do not yet exist, this will skip over
    # the DROP TABLE commands
    try:
        c.execute(command)
    except OperationalError, msg:
        print "Command skipped: ", msg


# For each of the 3 tables, query the database and print the contents
for table in ['ZooKeeper', 'Animal', 'Handles']:


    **# Plug in the name of the table into SELECT * query
    result = c.execute("SELECT * FROM %s;" % table);**

    # Get all rows.
    rows = result.fetchall();

    # \n represents an end-of-line
    print "\n--- TABLE ", table, "\n"

    # This will print the name of the columns, padding each name up
    # to 22 characters. Note that comma at the end prevents new lines
    for desc in result.description:
        print desc[0].rjust(22, ' '),

    # End the line with column names
    print ""
    for row in rows:
        for value in row:
            # Print each value, padding it up with ' ' to 22 characters on the right
            print str(value).rjust(22, ' '),
        # End the values from the row
        print ""

c.close()
conn.close()

【问题讨论】:

  • 您应该执行哪些 SQL 查询,1.1 和 1.2 的查询,还是只从每个表中获取所有内容?
  • 我想从 .sql 文件中运行 1.1 和 1.2(还有另外 6 个)。
  • 我相信我的速度有点太快了,您需要帮助理解代码还是需要帮助编辑代码来做一些额外的事情?
  • 可能两者兼而有之。我需要的所有 sql 都在 zookeeper.sql 中(并且应该留在那里)。然后,python 代码假设读取 sql 文件,创建表,填充它们(我认为我做得对),然后执行上面的查询(即 1.1、1.2)。

标签: python sql


【解决方案1】:

您的代码已经包含了一种从指定的 sql 文件中执行所有语句的绝妙方法

# Open and read the file as a single buffer
fd = open('ZooDatabase.sql', 'r')
sqlFile = fd.read()
fd.close()

# all SQL commands (split on ';')
sqlCommands = sqlFile.split(';')

# Execute every command from the input file
for command in sqlCommands:
    # This will skip and report errors
    # For example, if the tables do not yet exist, this will skip over
    # the DROP TABLE commands
    try:
        c.execute(command)
    except OperationalError, msg:
        print("Command skipped: ", msg)

将其包装在一个函数中,您可以重复使用它。

def executeScriptsFromFile(filename):
    # Open and read the file as a single buffer
    fd = open(filename, 'r')
    sqlFile = fd.read()
    fd.close()

    # all SQL commands (split on ';')
    sqlCommands = sqlFile.split(';')

    # Execute every command from the input file
    for command in sqlCommands:
        # This will skip and report errors
        # For example, if the tables do not yet exist, this will skip over
        # the DROP TABLE commands
        try:
            c.execute(command)
        except OperationalError, msg:
            print("Command skipped: ", msg)

使用它

executeScriptsFromFile('zookeeper.sql')

你说你被弄糊涂了

result = c.execute("SELECT * FROM %s;" % table);

在 Python 中,您可以使用称为字符串格式化的方法向字符串添加内容。

你有一个带有 %s 的字符串"Some string with %s",它是其他东西的占位符。要替换占位符,请在字符串后添加 %(“你想用什么替换它”)

例如:

a = "Hi, my name is %s and I have a %s hat" % ("Azeirah", "cool")
print(a)
>>> Hi, my name is Azeirah and I have a Cool hat

有点幼稚的例子,但应该很清楚。

现在,什么

result = c.execute("SELECT * FROM %s;" % table);

意思是,是不是用表变量的值代替了%s。

(创建于)

for table in ['ZooKeeper', 'Animal', 'Handles']:


# for loop example

for fruit in ["apple", "pear", "orange"]:
    print(fruit)
>>> apple
>>> pear
>>> orange

如果您还有其他问题,请戳我。

【讨论】:

  • 很高兴我的问题离线,但你如何戳 SOF?我插入了我认为您在谈论的内容并遇到了一堆错误。所以我仍然没有得到任何东西。 MPG
  • 此代码将尝试对所有 sql 文档执行空字符串查询。尾随分号将创建一个空字符串列表元素。试试: sqlCommands = filter(None, sqlFile.split(';'))
  • 这一直有效,直到您的 SQL 文件中有一个包含“;”的文本列
  • @TrevorJ.Smith 所有直接发布在 StackOverflow 上的代码均根据知识共享许可 see this post for more info 获得许可。不过,我不是律师,如果您认为在您的案件中可能有必要,请咨询律师。
  • @Azeirah 您的回答可能会导致 SQL 注入,您能否使其使用? 语法进行 SQL 格式化?
【解决方案2】:

在python中将外部脚本读入sqlite数据库的一种非常简单的方法是使用executescript()

import sqlite3

conn = sqlite3.connect('csc455_HW3.db')

with open('ZooDatabase.sql', 'r') as sql_file:
    conn.executescript(sql_file.read())

conn.close()

【讨论】:

    【解决方案3】:

    先确认表存在,如果不存在,创建表然后按照步骤操作。

    import sqlite3
    from sqlite3 import OperationalError
    
    conn = sqlite3.connect('Client_DB.db')
    c = conn.cursor()
    
    def execute_sqlfile(filename):
        
        c.execute("CREATE TABLE clients_parameters (adress text, ie text)")
        #
        fd = open(filename, 'r')
        sqlFile = fd.readlines()
        fd.close()
        lvalues = [tuple(v.split(';')) for v in sqlFile[1:] ]
        try:
            #print(command)
            c.executemany("INSERT INTO clients_parameters VALUES (?, ?)", lvalues)
        except OperationalError as msg:
            print ("Command skipped: ", msg)
    
    execute_sqlfile('clients.sql')
    
    print(c.rowcount)
    
    

    【讨论】:

      【解决方案4】:

      在我看来,这是不可能的

      解决方案:

      1. 在mysql服务器上导入.sql文件

      2. 之后

        import mysql.connector
        import pandas as pd
        

        然后您通过转换为数据框来使用 .sql 文件

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-05-14
        • 2020-10-11
        • 1970-01-01
        • 2011-05-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多