Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/62.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
选项,当出现错误并且脚本停止运行时,将在python中抛出其中一个异常。_Python_Mysql - Fatal编程技术网

选项,当出现错误并且脚本停止运行时,将在python中抛出其中一个异常。

选项,当出现错误并且脚本停止运行时,将在python中抛出其中一个异常。,python,mysql,Python,Mysql,这对我来说很有效: with open('schema.sql') as f: cursor.execute(f.read().decode('utf-8'), multi=True) 您可以使用其他数据库驱动程序吗? 如果是:您想要的是MySQL驱动程序 它支持通过传递Multi=True一次执行多个SQL语句 用分号拆分文件中的SQL语句是不必要的 简单示例(主要是从第二个链接复制和粘贴,我刚刚添加了从文件读取SQL): 我使用它将MySQL转储(通过将整个数据库导出到SQL文件而

这对我来说很有效:

with open('schema.sql') as f:
    cursor.execute(f.read().decode('utf-8'), multi=True)

您可以使用其他数据库驱动程序吗?
如果是:您想要的是MySQL驱动程序

它支持通过传递
Multi=True
一次执行多个SQL语句

用分号拆分文件中的SQL语句是不必要的

简单示例(主要是从第二个链接复制和粘贴,我刚刚添加了从文件读取SQL):

我使用它将MySQL转储(通过将整个数据库导出到SQL文件而在phpMyAdmin中创建)从*.SQL文件导入到数据库中。

如何使用?其思想是,您可以启动一个进程
pexpect.spawn(…)
,并等待该进程的输出包含某个模式
process.expect(pattern)

实际上,我使用它连接到mysql客户端并执行一些sql脚本

连接

import-pexpect
process=pexpect.spawn(“mysql”[“-u”、用户“-p”])
process.expect(“输入密码”)
process.sendline(密码)
process.expect(“mysql>”)
这样,密码就不会硬编码到命令行参数中(消除了安全风险)

执行甚至几个sql脚本

error=False
对于sql_脚本中的脚本:
process.sendline(“源{};”.format(脚本))
index=process.expect([“mysql>,“ERROR”])
#发生错误,请中断
如果索引==1:
错误=真
打破
如果没有错误:
#提交脚本的更改
process.sendline(“提交;”)
process.expect(“mysql>”)
打印“一切正常”
其他:
#不提交+打印错误消息
打印“您的脚本有错误”

请注意,您总是调用
expect(pattern)
,并且它匹配,否则将出现超时错误。我需要这段代码来执行几个sql脚本,并且只有在没有错误发生的情况下才提交它们的更改,但是它很容易适应只有一个脚本的用例。

下面是sqlite的一个示例(它也适用于MySQL)

示例文件.sql

show tables;
blow up;
show tables;
INSERT INTO actors (name)  VALUES  ('Evan Goldberg')   
INSERT INTO actors (name)  VALUES  ('Jay Baruchel')   
INSERT INTO actors (name)  VALUES  ('Ray Downey')
示例app.py

import sqlite3
from sqlite3 import OperationalError

#Connect to sqlite database
conn = sqlite3.connect('./database.db') 
cur  = conn.cursor()

#Create Table if not exist
create_table="""CREATE TABLE actors
( id INTEGER PRIMARY KEY AUTOINCREMENT,
  name VARCHAR NOT NULL);"""
try:
  execute = cur.execute(create_table)
except OperationalError as e:
  print(e)

#Read File line by line and execute sql
with open("file.sql") as f:  
     query = f.readlines() 
     for sql in query:
         execute = cur.execute(sql)
         conn.commit()

#Check if data was submitted
execute = cur.execute('Select * From actors Order By id asc Limit 3')
rows = cur.fetchall()
print(rows)

conn.close()
您应该看到这样的结果:

[(1, 'Evan Goldberg'), (2, 'Jay Baruchel'), (3, 'Ray Downey')]

如其中一条注释所述,如果您确定每个命令都以分号结尾,则可以执行以下操作:

import mysql.connector
connection = mysql.connector.connect(
    host=host,
    user=user,
    password=password
)

cursor = connection.cursor()

with open(script, encoding="utf-8") as f:
    commands = f.read().split(';')

for command in commands:
    cursor.execute(command)
    print(command)

connection.close()

我在这种方法中遇到了逃避问题。。。我有一个sql文件作为转储文件的输出。当您通过mysql命令行加载文件时,我想mysql会处理转义。但是python mysqldb希望您作为
line
传递的字符串已经转义。或者,它需要类似于
execute('SOME SQL COMMAND blah WITH PARAMS%s',PARAMS)
的内容,然后它将为您正确地转义
PARAMS
。。。但这在我描述的案例中不起作用。在这种情况下,@jotmicron的答案可能更好。幸运的是,我可以使用django fixture来代替。但是如果你需要使用输出,你必须自己解析它,这是一个很大的麻烦。这是正确的。但是,我从未遇到过必须使用SQL文件输出的情况。当我想将mysql转储文件使用到另一个数据库中时,我主要使用这种方法,该数据库只有INSERT和CREATE以及类似的语句,这些语句的输出通常不会在以后使用。Hmm。很简单,但我有点担心安全问题。您必须在命令行上提供密码,MySQL客户端抱怨在终端上提供密码时不安全。我想你最终会在你的流程列表中找到它,等等。看看我的答案,这是一个基于这个概念的更健壮的版本。如果你必须全面地处理结果,那么你应该更可能使用MySQLdb(或其他等效工具),而不是试图解析这个输出。正如@jdferreira所说,如果您正在执行这样一个脚本,那么您似乎不太可能需要输出来达到这样的目的。该脚本的性质是动态的和开放的。您将如何控制要从中解析输出的输入?如果您想纯粹为了错误检测而解析它,那么可以通过stdout与stderr的比较得到它。在我的回答中,我对错误消息进行了一些(令人不快的)解析。在python 3中,您还必须将str编码为字节:
output=process.communicate(str.encode('source'+filename))[0]
这似乎有可能保持简单,但是,您知道文件中的SQL注释是否有效吗?例如,db.execute('SELECT 1;\n--comment here\n SELECT 2;\n')或db.execute('SELECT 1;--comment here SELECT 2;')。如果你知道文件中没有任何注释,那么打开MYSQL\u选项\u MULTI\u STATEMENTS\u将是一个不错的选择。这会失败,因为任何注释对我来说都是完美的,包括注释,这应该是最好的正确答案。。。回想起来。(2017)为什么这个答案没有任何评论。。。。这应该是正确的,非常好,它似乎是大文件的唯一解决方案。对我来说,我只使用line.strip().startswith('--')和line.strip().endswith(';')更改了两个re。并从_mysql_异常导入这两个错误。这很好用,很容易修补到python 3。有人知道如何调整它以支持吗<代码>/*。。。评论。。。评论。。。评论。。。评论*/它实际上和@Denzel的答案一样低效。唯一的问题是文件描述符从未关闭
\n
不是唯一可能的分隔符。像这里的几个答案一样,这并不能说明这样一个事实:你可以(和脚本经常这样做)在处理的中间改变分隔符本身。另外,您可以将MySQL配置为默认使用不同的分隔符。定义sql函数、过程、触发器等时,通常使用
$$
作为delim
-- SQL script to bootstrap the DB:
--
CREATE USER 'x'@'%' IDENTIFIED BY 'x';
GRANT ALL PRIVILEGES ON mystore.* TO 'x'@'%';
GRANT ALL ON `%`.* TO 'x'@`%`;
FLUSH PRIVILEGES;
--
--
CREATE DATABASE oozie;
GRANT ALL PRIVILEGES ON oozie.* TO 'oozie'@'localhost' IDENTIFIED BY 'oozie';
GRANT ALL PRIVILEGES ON oozie.* TO 'oozie'@'%' IDENTIFIED BY 'oozie';
FLUSH PRIVILEGES;
--
USE oozie;
--
CREATE TABLE `BUNDLE_ACTIONS` (
  `bundle_action_id` varchar(255) NOT NULL,
  `bundle_id` varchar(255) DEFAULT NULL,
  `coord_id` varchar(255) DEFAULT NULL,
  `coord_name` varchar(255) DEFAULT NULL,
  `critical` int(11) DEFAULT NULL,
  `last_modified_time` datetime DEFAULT NULL,
  `pending` int(11) DEFAULT NULL,
  `status` varchar(255) DEFAULT NULL,
  `bean_type` varchar(31) DEFAULT NULL,
  PRIMARY KEY (`bundle_action_id`),
  KEY `I_BNDLTNS_DTYPE` (`bean_type`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
--
--
def exec_sql_file(cursor, sql_file):
    print "\n[INFO] Executing SQL script file: '%s'" % (sql_file)
    statement = ""

    for line in open(sql_file):
        if re.match(r'--', line):  # ignore sql comment lines
            continue
        if not re.search(r';$', line):  # keep appending lines that don't end in ';'
            statement = statement + line
        else:  # when you get a line ending in ';' then exec statement and reset for next statement
            statement = statement + line
            #print "\n\n[DEBUG] Executing SQL statement:\n%s" % (statement)
            try:
                cursor.execute(statement)
            except (OperationalError, ProgrammingError) as e:
                print "\n[WARN] MySQLError during execute statement \n\tArgs: '%s'" % (str(e.args))

            statement = ""
for line in open(PATH_TO_FILE).read().split(';\n'):
    cursor.execute(line)
f = open(filename, 'r')
query = " ".join(f.readlines())
c.execute(query)
import MySQLdb
from configdb import DB_HOST, DB_PASS, DB_USER, DB_DATABASE_NAME

db = MySQLdb.connect(host=DB_HOST,    # your host, usually localhost
                     user=DB_USER,         # your username
                     passwd=DB_PASS,  # your password
                     db=DB_DATABASE_NAME)        # name of the data base

cur = db.cursor()

PATH_TO_FILE = "db-testcases.sql"

fullLine = ''

for line in open(PATH_TO_FILE):
  tempLine = line.strip()

  # Skip empty lines.
  # However, it seems "strip" doesn't remove every sort of whitespace.
  # So, we also catch the "Query was empty" error below.
  if len(tempLine) == 0:
    continue

  # Skip comments
  if tempLine[0] == '#':
    continue

  fullLine += line

  if not ';' in line:
    continue

  # You can remove this. It's for debugging purposes.
  print "[line] ", fullLine, "[/line]"

  try:
    cur.execute(fullLine)
  except MySQLdb.OperationalError as e:
    if e[1] == 'Query was empty':
      continue

    raise e

  fullLine = ''

db.close()
from os import system
USERNAME = "root"
PASSWORD = "root"
DBNAME = "pablo"
HOST = "localhost"
PORT = 3306
FILE = "file.sql"
command = """mysql -u %s -p"%s" --host %s --port %s %s < %s""" %(USERNAME, PASSWORD, HOST, PORT, DBNAME, FILE)
system(command)
[client]
user     = XXXXXXX
password = YYYYYYY
#!/usr/bin/python

import os
import sys
import MySQLdb
from subprocess import Popen, PIPE, STDOUT

__MYSQL_CLIENT_PATH = "mysql"

__THIS_DIR = os.path.dirname( os.path.realpath( sys.argv[0] ) )

__DB_CONFIG_PATH    = os.path.join( __THIS_DIR, "db-creds.cfg" )
__DB_CONFIG_SECTION = "client"

__DB_CONN_HOST = "localhost"
__DB_CONN_PORT = 3306

# ----------------------------------------------------------------

class MySqlScriptError( Exception ):

    def __init__( self, dbName, scriptPath, stdOut, stdErr ):
        Exception.__init__( self )
        self.dbName = dbName
        self.scriptPath = scriptPath
        self.priorOutput = stdOut
        self.errorMsg = stdErr                
        errNumParts = stdErr.split("(")        
        try : self.errorNum = long( errNumParts[0].replace("ERROR","").strip() )
        except: self.errorNum = None        
        try : self.sqlState = long( errNumParts[1].split(")")[0].strip() )
        except: self.sqlState = None

    def __str__( self ): 
        return ("--- MySqlScriptError ---\n" +
                "Script: %s\n" % (self.scriptPath,) +
                "Database: %s\n" % (self.dbName,) +
                self.errorMsg ) 

    def __repr__( self ): return self.__str__()

# ----------------------------------------------------------------

def databaseLoginParms() :        
    from ConfigParser import RawConfigParser
    parser = RawConfigParser()
    parser.read( __DB_CONFIG_PATH )   
    return ( parser.get( __DB_CONFIG_SECTION, "user" ).strip(), 
             parser.get( __DB_CONFIG_SECTION, "password" ).strip() )

def databaseConn( username, password, dbName ):        
    return MySQLdb.connect( host=__DB_CONN_HOST, port=__DB_CONN_PORT,
                            user=username, passwd=password, db=dbName )

def executeSqlScript( dbName, scriptPath, ignoreErrors=False ) :       
    scriptDirPath = os.path.dirname( os.path.realpath( scriptPath ) )
    sourceCmd = "SOURCE %s" % (scriptPath,)
    cmdList = [ __MYSQL_CLIENT_PATH,                
               "--defaults-extra-file=%s" % (__DB_CONFIG_PATH,) , 
               "--database", dbName,
               "--unbuffered" ] 
    if ignoreErrors : 
        cmdList.append( "--force" )
    else:
        cmdList.extend( ["--execute", sourceCmd ] )
    process = Popen( cmdList 
                   , cwd=scriptDirPath
                   , stdout=PIPE 
                   , stderr=(STDOUT if ignoreErrors else PIPE) 
                   , stdin=(PIPE if ignoreErrors else None) )
    stdOut, stdErr = process.communicate( sourceCmd if ignoreErrors else None )
    if stdErr is not None and len(stdErr) > 0 : 
        raise MySqlScriptError( dbName, scriptPath, stdOut, stdErr )
    return stdOut
if __name__ == "__main__": 

    ( username, password ) = databaseLoginParms()
    dbName = "ExampleDatabase"

    print "MySQLdb Test"
    print   
    conn = databaseConn( username, password, dbName )
    cursor = conn.cursor()
    cursor.execute( "show tables" )
    print cursor.fetchall()
    cursor.close()
    conn.close()
    print   

    print "-----------------"
    print "Execute Script with ignore errors"
    print   
    scriptPath = "test.sql"
    print executeSqlScript( dbName, scriptPath, 
                            ignoreErrors=True )
    print   

    print "-----------------"
    print "Execute Script WITHOUT ignore errors"                            
    print   
    try : print executeSqlScript( dbName, scriptPath )
    except MySqlScriptError as e :        
        print "dbName: %s" % (e.dbName,)
        print "scriptPath: %s" % (e.scriptPath,)
        print "errorNum: %s" % (str(e.errorNum),)
        print "sqlState: %s" % (str(e.sqlState),)
        print "priorOutput:"        
        print e.priorOutput
        print
        print "errorMsg:"
        print e.errorMsg           
        print
        print e
    print   
show tables;
blow up;
show tables;
with open('schema.sql') as f:
    cursor.execute(f.read().decode('utf-8'), multi=True)
import mysql.connector

file = open('test.sql')
sql = file.read()

cnx = mysql.connector.connect(user='uuu', password='ppp', host='hhh', database='ddd')
cursor = cnx.cursor()

for result in cursor.execute(sql, multi=True):
  if result.with_rows:
    print("Rows produced by statement '{}':".format(
      result.statement))
    print(result.fetchall())
  else:
    print("Number of rows affected by statement '{}': {}".format(
      result.statement, result.rowcount))

cnx.close()
INSERT INTO actors (name)  VALUES  ('Evan Goldberg')   
INSERT INTO actors (name)  VALUES  ('Jay Baruchel')   
INSERT INTO actors (name)  VALUES  ('Ray Downey')
import sqlite3
from sqlite3 import OperationalError

#Connect to sqlite database
conn = sqlite3.connect('./database.db') 
cur  = conn.cursor()

#Create Table if not exist
create_table="""CREATE TABLE actors
( id INTEGER PRIMARY KEY AUTOINCREMENT,
  name VARCHAR NOT NULL);"""
try:
  execute = cur.execute(create_table)
except OperationalError as e:
  print(e)

#Read File line by line and execute sql
with open("file.sql") as f:  
     query = f.readlines() 
     for sql in query:
         execute = cur.execute(sql)
         conn.commit()

#Check if data was submitted
execute = cur.execute('Select * From actors Order By id asc Limit 3')
rows = cur.fetchall()
print(rows)

conn.close()
[(1, 'Evan Goldberg'), (2, 'Jay Baruchel'), (3, 'Ray Downey')]
import mysql.connector
connection = mysql.connector.connect(
    host=host,
    user=user,
    password=password
)

cursor = connection.cursor()

with open(script, encoding="utf-8") as f:
    commands = f.read().split(';')

for command in commands:
    cursor.execute(command)
    print(command)

connection.close()