2017-08-01 155 views
0

我从MSSQL工作台产生TEST.SQL文件,如下所示:如何通过python解析sql文件?

 /****** Object: Database [sample_test] Script Date: 7/19/2017 3:00:55 PM 
    ******/ 
    USE [sample_test] 
    GO 
    ALTER DATABASE [sample_test] SET COMPATIBILITY_LEVEL = 100 
    GO 
    IF (1 = FULLTEXTSERVICEPROPERTY('IsFullTextInstalled')) 
    begin 
    EXEC [sample_test].[dbo].[sp_fulltext_database] @action = 'enable' 
    end 
    GO 
    ALTER DATABASE [sample_test] SET ANSI_NULL_DEFAULT OFF 
    GO 
    ALTER DATABASE [sample_test] SET ANSI_NULLS OFF 
    GO 
    ALTER DATABASE [sample_test] SET ANSI_PADDING OFF 
    GO 
    ALTER DATABASE [sample_test] SET ANSI_WARNINGS OFF 
    GO 
    USE [sample_test] 
    GO 
    /****** Object: Schema [sample_test] Script Date: 7/19/2017 3:00:55 PM ******/ 
    CREATE SCHEMA [sample_test] 
    GO 
    /****** Object: Table [sample_test].[test_items] Script Date: 7/19/2017 3:00:55 PM ******/ 
    SET ANSI_NULLS ON 
    GO 
    SET QUOTED_IDENTIFIER ON 
    GO 
    CREATE TABLE [sample_test].[test_items](
     [test_detail] [nvarchar](max) NOT NULL, 
     [test_id] [int] IDENTITY(1,1) NOT NULL, 
     [test_date_time] [datetime2](0) NOT NULL, 
    CONSTRAINT [PK_test_items_test_id] PRIMARY KEY CLUSTERED 
    (
     [test_id] ASC 
    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
    ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY] 

    GO 
    /****** Object: Table [sample_test].[test_history] Script Date: 7/19/2017 3:00:55 PM ******/ 
    SET ANSI_NULLS ON 
    GO 
    SET QUOTED_IDENTIFIER ON 
    GO 
    CREATE TABLE [sample_test].[test_history](
     [test_history_id] [int] IDENTITY(1,1) NOT NULL, 
     [test_flag] [int] NOT NULL, 
     [test_date_time] [datetime2](0) NOT NULL, 
    CONSTRAINT [PK_test_history_test_history_id] PRIMARY KEY CLUSTERED 
    (
     [test_history_id] ASC 
    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
    ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY] 

    GO 
    INSERT INTO [sample_test].[test_items] ([test_detail], [test_id]) VALUES (0, 'IN') 
    INSERT INTO [sample_test].[test_items] ([test_detail], [test_id]) VALUES (0, 'OUT') 
    INSERT INTO [sample_test].[test_items] ([test_detail], [test_id]) VALUES (1, 'NONE') 

需要执行上的一些不同的服务器上面的SQL脚本,并获得该服务器上的表。 对于具有一个python脚本作为目的:

import pymssql 
    conn = pymssql.connect(host='xyz', user='abc', password='123', database='sks') 
    cursor=conn.cursor() 

    with open("test.sql", "r") as inp:  
     for line in inp.read().split("\r"): 
      cursor.execute(line)   
    conn.commit() 
    conn.close() 

但它抛出的错误作为其无法解析和一些其他的语句。然后我执行的SQL脚本如下:

import pymssql 

    conn = pymssql.connect(host='xyz', user='abc', password='123', database='sks') 
    cursor=conn.cursor() 

    sql1=""" 
    USE [sample_test] 
    /****** Object: Schema [sample_test] Script Date: 7/19/2017 3:00:55 PM ******/ 
    CREATE SCHEMA [sample_test] 
    /****** Object: Table [sample_test].[test_items] Script Date: 7/19/2017 3:00:55 PM ******/ 
    SET ANSI_NULLS ON 
    SET QUOTED_IDENTIFIER ON 
    CREATE TABLE [sample_test].[test_items](
     [test_detail] [nvarchar](max) NOT NULL, 
     [test_id] [int] IDENTITY(1,1) NOT NULL, 
     [test_date_time] [datetime2](0) NOT NULL, 
    CONSTRAINT [PK_test_items_test_id] PRIMARY KEY CLUSTERED 
    (
     [test_id] ASC 
    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
    ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY] 

    /****** Object: Table [sample_test].[test_history] Script Date: 7/19/2017 3:00:55 PM ******/ 
    SET ANSI_NULLS ON 
    SET QUOTED_IDENTIFIER ON 
    CREATE TABLE [sample_test].[test_history](
     [test_history_id] [int] IDENTITY(1,1) NOT NULL, 
     [test_flag] [int] NOT NULL, 
     [test_date_time] [datetime2](0) NOT NULL, 
    CONSTRAINT [PK_test_history_test_history_id] PRIMARY KEY CLUSTERED 
    (
     [test_history_id] ASC 
    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
    ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY] 

    INSERT INTO [sample_test].[test_items] ([test_detail], [test_id]) VALUES (0, 'IN_RETRIVAL') 
    INSERT INTO [sample_test].[test_items] ([test_detail], [test_id]) VALUES (0, 'IN_RETRIVAL') 
    INSERT INTO [sample_test].[test_items] ([test_detail], [test_id]) VALUES (1, 'RETRIVAL_FAILED') 

    """ 
    cursor.execute(sql1)  
    sql2= """ 
    CREATE NONCLUSTERED INDEX [fk_case_id_idx] ON [sample_test].[test_items] 
    (
     [case_id] ASC 
    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 

    """ 
    cursor.execute(sql2) 
    conn.commit() 
    conn.close() 

现在上面的一块工作正常,创建与foreingnkey和priary键约束沿表。 我现在想要的是以最初应该执行创建表的方式解析test.sql文件,然后执行CREATE NONCLUSTERED INDEX。 那么,我该如何解析test.sql以我分段执行脚本的方式。

+0

你应该尽量做一个你的代码的最小例子。请参阅:https://stackoverflow.com/help/mcve – Enfenion

+0

这里的挑战在于,TSQL(SQL Server的方言)不需要在可能是用于拆分的方便分隔符的语句之间使用分号。 – Parfait

回答

1

为什么你正试图在不同的步骤解析它?它可以一次运行。

无论如何,你正在寻找的方式是分裂你的脚本GO。然后,你可以indepedently运行每个部分,例如像这样(不,虽然测试):

with open("test.sql", "r") as inp: 
    for section in inp.read().split("GO"): 
     cursor.execute(section) 
0

如果权限被授予连接的用户,可以考虑从这些SQL命令创建一个存储过程,然后执行存储程序:

import pymssql 
conn = pymssql.connect(host='xyz', user='abc', password='123', database='sks') 
cursor = conn.cursor() 

# READ SQL FILE CONTENT INTO STRING 
with open("test.sql", "r") as f: 
    sqlstr = f.read() 

# DROP STORED PROC IF EXISTS 
cur.execute("IF EXISTS (SELECT * FROM sys.objects" \ 
      "   WHERE type='P' AND name='myStoredProc')" \ 
      " DROP PROCEDURE myStoredProc" 
conn.commit() 

# CREATE STORED PROC (CONCATENATING SQL STRING) 
cur.execute("CREATE PROCEDURE myStoredProc AS" + \ 
      " BEGIN" + \ 
      " {}".format(sqlstr) + \ 
      " END") 
conn.commit() 

# EXECUTE STORED PROC 
cur.execute("EXEC myStoredProc")