SpatiaLite.py 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. # -*- coding: utf-8 -*-
  2. __author__ = 'wanger'
  3. __date__ = '2024-08-27'
  4. __copyright__ = '(C) 2024 by siwei'
  5. __revision__ = '1.0'
  6. import sqlite3
  7. class SpatiaLiteUtils:
  8. def __init__(
  9. self,
  10. dbpath: str
  11. ):
  12. self.dbpath = dbpath
  13. # 连接到数据库
  14. self.conn = sqlite3.connect(dbpath)
  15. self.cursor = self.conn.cursor()
  16. self.conn.enable_load_extension(True)
  17. self.conn.execute("PRAGMA synchronous = OFF")
  18. self.conn.execute("PRAGMA cache_size = -20000") # In KB
  19. self.conn.execute("PRAGMA temp_store = MEMORY")
  20. self.conn.execute("SELECT load_extension('mod_spatialite');")
  21. print("mod_spatialite loaded successfully.")
  22. def execute(self, sql):
  23. self.cursor.execute(sql)
  24. rows = self.cursor.fetchall()
  25. return rows
  26. def executescript(self, sql, params):
  27. self.cursor.executescript(sql)
  28. print(f"Script executed successfully.{sql}")
  29. print(f"同步输入输出表字段信息及属性关联")
  30. tables = params["intable_s"]
  31. tablet = params["outtable"]
  32. self.synchronizeFields(tables=tables, tablet=tablet)
  33. print(f"{tables}字段和属性已关联同步更新到{tablet}")
  34. def enable_load_extension(self, bool):
  35. self.conn.enable_load_extension(bool)
  36. # 同步字段
  37. def synchronizeFields(self, tables, tablet):
  38. # 获取 tables 的字段信息
  39. self.cursor.execute(f"pragma table_info({tables});")
  40. fields = self.cursor.fetchall()
  41. # 添加字段到 tablet
  42. insertfield = []
  43. for field in fields:
  44. field_name, field_type = field[1], field[2]
  45. if field_name != "id" and field_name != "ogc_fid" and field_name != "objectid" and field_name.lower() != "geometry": # 排除 id 字段
  46. insertfield.append(field_name)
  47. self.cursor.execute(f"alter table {tablet} add column {field_name} {field_type};")
  48. # 更新 tablet 中的数据
  49. update_query = f"update {tablet} set "
  50. update_query += ", ".join(
  51. [f"{field} = (select {field} from {tables} where ogc_fid = {tablet}.sid)" for field in insertfield])
  52. print(update_query)
  53. self.cursor.execute(update_query)
  54. self.conn.commit()
  55. def queryCount(self, tablename):
  56. self.cursor.execute(f"SELECT count(1) FROM {tablename};")
  57. rows = self.cursor.fetchall()
  58. return rows[0][0]
  59. # 重置数据库
  60. def resetDb(self):
  61. # 获取所有表名,排除系统表
  62. self.cursor.execute("""-- 删除所有表
  63. select 'drop table if exists ' || name || ';'
  64. from sqlite_master
  65. where type='table' and name not like 'sqlite_%' and (name like '%topology%' or name like '%temp%')
  66. union all
  67. -- 删除所有索引
  68. select 'drop index if exists ' || name || ';'
  69. from sqlite_master
  70. where type='index' and (name like '%topology%' or name like '%temp%')
  71. union all
  72. -- 删除所有视图
  73. select 'drop view if exists ' || name || ';'
  74. from sqlite_master
  75. where type='view' and (name like '%temp%' or name like '%view%')
  76. union all
  77. -- 删除所有触发器
  78. select 'drop trigger if exists ' || name || ';'
  79. from sqlite_master
  80. where type='trigger' and name like '%topology%';""")
  81. tables = self.cursor.fetchall()
  82. # 循环删除每个表
  83. # for sql in tables:
  84. # self.cursor.execute(sql[0])
  85. # 提交更改并关闭连接
  86. self.conn.commit()
  87. def closeDb(self):
  88. self.cursor.close()
  89. self.conn.close()
  90. # db = SpatiaLiteUtils(dbpath="D:\\temp\\output.sqlite")
  91. # db.synchronizeFields(tables="topology_in_table_5226c4d3c7a84b2e901c5032cbd299fe", tablet="topology_out_table_5226c4d3c7a84b2e901c5032cbd299fe")
  92. # # db.resetDb()
  93. # db.closeDb()