能否通过Python的sqlite3接口创建普通视图及JOIN关联视图?
问题解答
是否支持通过Python/sqlite3创建视图
完全支持。CREATE VIEW属于标准SQLite DDL语句,和建表、查询操作一样,都可以通过cursor.execute()执行,无论是单表普通视图、多表JOIN关联视图都可以正常创建,和直接在sqlite3命令行执行的效果完全一致。
现有代码不生效的原因排查
你的代码存在多处语法和逻辑错误,导致没有正常执行:
- 连接对象获取错误:
create_connection是你定义的全局函数,不是conn对象的方法,你写的conn.create_connection(database)既没有对conn变量赋值,还会触发属性不存在错误,正确写法是conn = create_connection(database) - 语法关键字错误:
if conn is Not None里的Not大写不符合Python语法,正确应为小写的not - 变量名不匹配:你定义的SQL语句变量是
sqlite_create_view1、sqlite_create_view2、sqlite_create_final,但调用create_view时传的是sql_create_view1、sql_create_view2、final,变量名完全对不上,会触发NameError - 缺少必要的导入和提交操作:你没有导入
sqlite3.Error类,同时DDL操作建议主动调用conn.commit()提交,避免事务未写入磁盘 - 缺少入口调用:你只定义了main函数,没有执行
main(db)的入口代码,整个逻辑根本不会运行
修正后的可用代码
import sqlite3 from sqlite3 import Error db = "/path/to/db/dbfile" def create_connection(sqliteDB): conn=None try: conn=sqlite3.connect(sqliteDB) return conn except Error as e: print(f"连接错误:{e}") return conn def create_view(conn, create_view_sql): try: c=conn.cursor() c.execute(create_view_sql) conn.commit() # 主动提交修改 print(f"视图创建成功:{create_view_sql.split('as')[0].strip()}") except Error as e: print(f"创建视图错误:{e}") def main(db): database = db # 视图1:单表视图 sqlite_create_view1 = """CREATE VIEW IF NOT EXISTS view1 as select id, b, c from TABLE1;""" # 视图2:单表视图 sqlite_create_view2 = """CREATE VIEW IF NOT EXISTS view2 as select id, d, e, f from TABLE2;""" # 最终关联视图 sqlite_create_final = """CREATE VIEW IF NOT EXISTS final as select a.id, a.b, a.c, b.d, b.e, b.f from view1 a left join view2 b using (id); """ # 如果你后续要直接从原始表创建最终视图,直接替换上面的sql即可,示例: # sqlite_create_final = """CREATE VIEW IF NOT EXISTS final as # select a.id, a.b, a.c, b.d, b.e, b.f # from TABLE1 a # left join TABLE2 b using (id); """ conn = create_connection(database) if conn is not None: conn.text_factory = str create_view(conn, sqlite_create_view1) create_view(conn, sqlite_create_view2) create_view(conn, sqlite_create_final) conn.close() else: print ("Error - 无法创建数据库连接") if __name__ == "__main__": main(db)
注:加了
IF NOT EXISTS避免重复创建视图时报错,同时去掉了最终视图里重复的b.id字段,因为using(id)关联后两个id字段值一致,重复返回没有必要。
内容的提问来源于stack exchange,提问作者ClareFG
相关产品推荐
相关产品推荐

