2017-08-01 137 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")