SQLAlchemy Only Returns List Line if there are Carriage Returns in the Row (SQL Server)

tag5nh1u  于 2023-10-15  发布在  SQL Server
关注(0)|答案(1)|浏览(145)

I have an SQL query that generates the DDL to create tables based on the existing schema. I am running this to copy the schema to another database for backup purposes. I do not have permission to do it the normal way in SQL Server, so I'm using this other way.

Here is the DDL text that my query should return (and I have verified that the query returns in SSMS); it is only one row (and column) with the header name "DDL":

  1. SET NOCOUNT OFF;
  2. IF OBJECT_ID('[<schema_name>].[<table_name>]','SN') IS NOT NULL DROP SYNONYM [<schema_name>].[<table_name>];
  3. IF OBJECT_ID('[<schema_name>].[<table_name>]','U') IS NOT NULL DROP TABLE [<schema_name>].[<table_name>];
  4. RAISERROR('CREATE TABLE %s',10,1, '[<schema_name>].[<table_name>]') WITH NOWAIT;
  5. CREATE TABLE [<schema_name>].[<table_name>] (
  6. ... column definitions ...
  7. )
  8. RAISERROR('CREATING INDEXES OF %s',10,1, '[<schema_name>].[<table_name>]') WITH NOWAIT;

However, sqlachemy only returns the last line:

  1. RAISERROR('CREATING INDEXES OF %s',10,1, '[<schema_name>].[<table_name>]') WITH NOWAIT;

And here's the python code around where this is pulled:

  1. def get_create_ddls(table_name_list: list, conn) -> list:
  2. fd = open('CreateCreateDDL.sql', 'r')
  3. original_query = fd.read()
  4. fd.close()
  5. return_list = []
  6. for name in table_name_list:
  7. # prefixed the views as "V_"
  8. isView = name[:2] == "V_"
  9. if isView:
  10. tbl_insert_str = "('" + name[2:] + "')"
  11. else:
  12. tbl_insert_str = "('" + name + "')"
  13. query = original_query.replace("<INSERT_TABLE_NAME_HERE>", tbl_insert_str, 1)
  14. result = conn.execute(sqlalchemy.text(query))
  15. # TODO: Only reading last line of the row
  16. value_str = ""
  17. for row in result:
  18. temp_value = row.DDL
  19. value_str += temp_value
  20. print(value_str)
  21. if isView:
  22. # put the "V_" back into the CREATE statement
  23. view_name = name[2:(name.find("].[") + 3)] + "V_" + name[(name.find("].[") + 3):]
  24. value_str = value_str.replace(name[2:], view_name)
  25. return_list.append(value_str)
  26. return return_list

How can I fix this without going in and manually removing every carriage return from the source query? There are a lot of them.

mm5n2pyu

mm5n2pyu1#

I'm going to leave the question up because I think a general answer would be more suitable (i.e. a solution for queries that return cells with text that have carriage returns in them), but in the script that was generating this DDL, the script defines the carriage return like below:

  1. DECLARE @CR NVARCHAR(max) = NCHAR(13);

and then uses @CR for carriage returns the rest of the script. So, the solution was just to use a different delimiter:

  1. DECLARE @CR NVARCHAR(max) = NCHAR(32); -- space

Kudos to ildanny and devart for the script that generates the DDL mentioned above.

相关问题