PostgreSQL 学习之使用psycopg2 操作之数据库不存在才创建
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了PostgreSQL 学习之使用psycopg2 操作之数据库不存在才创建,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含5933字,纯文字阅读大概需要9分钟。
内容图文
需求
自己的一款软件 GitHub 地址,关于PostgreSQL 已经设置成运行后自动创建序列,表和函数,但是数据库还是要手动去创建,很不方便,想使用创建序列和表同样的方法,去自动创建数据库
过程
DDL 语句如下:
DB_NAME = """ CREATE DATABASE if not exists {}; ALTER DATABASE {} OWNER TO postgres; """.format(DATABASE_NAME, DATABASE_NAME)发现会报一个DDL 语句语法错误
psycopg2.ProgrammingError: syntax error at or near "not" LINE 2: CREATE DATABASE if not exists test_classs;
创建序列和表的时候都没问题啊(函数我使用的是先删除,后创建),这怎么报错了?本着先运行成功,再实现功能的原则,我把“if not exists”给去掉,结果还是报错:
psycopg2.InternalError: CREATE DATABASE cannot run inside a transaction block
不能在事务块中创建数据库,大概意思就是这样不安全吧,百度加谷歌,有两种方法:
1.在 psycopg2 extensions 里使用 ISOLATION_LEVEL_AUTOCOMMIT,原理就是让连接发出命令时不启动任何事务,看常量名字,字面意思也是自动提交,并且不需要commit()或rollback()如:
import psycopg2 from psycopg2.extensions import ISOLATION_LEVEL_AUTOCOMMIT # <-- ADD THIS LINE con = psycopg2.connect(...) con.set_isolation_level(ISOLATION_LEVEL_AUTOCOMMIT) # <-- ADD THIS LINE cur = con.cursor() cur.execute("CREATE DATABASE %s ;" % self.db_name) cur.close() con.close()
2.让连接处于自动提交模式,使用连接对象的autocommit 属性,如:
import psycopg2 con = psycopg2.connect(...) con.autocommit = True cur = con.cursor() cur.execute(‘CREATE DATABASE {};‘.format(db_name)) cur.close() # 如果连接不关闭,则需要改回连接对象的autocommit 属性 con.autocommit = False # 如果连接关闭,则不需要执行上面这行代码 # con.close()
但是当我运行的时候,还是遇到了另外一个错误:
psycopg2.InternalError: CREATE DATABASE cannot be executed from a function or multi-command string
从字面意思上看,是不能在函数中创建数据库,且不能在多命令的字符串中创建数据库,函数我这里没用,只能是多行命令了,看了一下自己的DDL 语句,发现自己复制创建表的DDL 语句的部分有点多了。。从最简单的做起吧,毕竟上面的这两个例子都没有问题,将DDL 语句改为:
DB_NAME = """ CREATE DATABASE {}; """.format(DATABASE_NAME)
再次运行,虽然有一丢丢慢,但是还是创建成功了,但是在这里,我建议使用第二种方法,因为简单,不用再导入这个很长的常量,而且控制还很方便,比如下面这个需求,创建第一个数据库,创建第二个数据库(怎么会有这么奇葩的需求,哈哈,都是为了举例方便)
import psycopg2 from psycopg2.extensions import ISOLATION_LEVEL_AUTOCOMMIT,ISOLATION_LEVEL_DEFAULT DATABASE_NAME = ‘test_classs‘ DATABASE_NAME2 = ‘test_classssssss‘ DB_NAME = """ CREATE DATABASE {}; """.format(DATABASE_NAME) DB_NAME2 = """ CREATE DATABASE {}; """.format(DATABASE_NAME2) conn = psycopg2.connect(...) conn.set_isolation_level(ISOLATION_LEVEL_AUTOCOMMIT) cur = conn.cursor() cur.execute(DB_NAME) conn.set_isolation_level(ISOLATION_LEVEL_DEFAULT) cur.execute(DB_NAME2) cur.close() conn.close()
看到了吧,你需要导入两个很长很长的变量名,当然,在IDE 的提示下,这样其实也不费事,但是我总感觉这样不怎么优雅,毕竟是Python,不优雅怎么行?所以我们可以使用另外一种方式:
import psycopg2 DATABASE_NAME = ‘test_classs‘ DATABASE_NAME2 = ‘test_classssssss‘ DB_NAME = """ CREATE DATABASE {}; """.format(DATABASE_NAME) DB_NAME2 = """ CREATE DATABASE {}; """.format(DATABASE_NAME2) conn = psycopg2.connect(...) conn.autocommit = True cur = conn.cursor() cur.execute(DB_NAME) conn.autocommit = False cur.execute(DB_NAME2) cur.close() conn.close()
效果是一样的,看着是不是舒服很多了?
好吧,现在我们的数据库是可以创建了,那么怎么样实现如果不存在就创建,存在就不处理呢?
既然不能像‘MySQL’那样用‘if not exists’来创建数据库,那么只能换另外一种思路了,先查询看看这个数据库是否存在,如果不存在就设置自动提交然后创建,如果存在,就不做处理,excuse me?这是换思路了吗?咳咳。。好吧,思路没变,只是过程用代码实现了而已。。具体代码如下:
import psycopg2 DATABASE_NAME = ‘test_classss‘ DB_NAME_EXIST = """ select * from pg_database where datname=‘{}‘; """.format(DATABASE_NAME) DB_NAME = """ CREATE DATABASE {}; """.format(DATABASE_NAME) conn = psycopg2.connect(...) cur = conn.cursor() cur.execute(DB_NAME_EXIST) result = cur.fetchall() if result == []: conn.autocommit = True cur.execute(DB_NAME) conn.autocommit = False else: print(‘{} is exist‘.format(DATABASE_NAME)) cur.close() conn.close()
注意,ALL_DB_NAME 这条SQL 语句的条件后面占位符{}必须用引号引起来,否则会报 column "test_class" does not exist 的错误
测试了一下,貌似没有问题,那么改用一个不存在的数据库看看,果然,没有我想的那么简单。。
conn.autocommit = True
psycopg2.ProgrammingError: set_session cannot be used inside a transaction
百度了一下,也没找到答案,不过根据字面意思,肯定是和事务有关,先尝试了一个最笨的方法,就是查询后记录查询结果,然后把游标和连接都关闭,然后再创建新的连接,新的游标,根据结果去创建数据库,或者不处理,发现没有问题,虽然感觉怪怪的,但是也蛮开心的,就在要往博客园上记下解决方法的时候,忽然想到了,把上次的查询后的给提交一下不就OK 了?快被自己蠢哭了,这也是为什么我打了那么多字,而不直接上代码的原因,这是经验的不足,也是数据库知识的不足,脸红,直接上代码吧,其实就加一行代码就解决了。
结果
import psycopg2 DATABASE_NAME = ‘test_classss‘ DB_NAME_EXIST = """ select * from pg_database where datname=‘{}‘; """.format(DATABASE_NAME) DB_NAME = """ CREATE DATABASE {}; """.format(DATABASE_NAME) conn = psycopg2.connect(...) cur = conn.cursor() cur.execute(DB_NAME_EXIST) conn.commit() # <-- ADD THIS LINE result = cur.fetchall() if result == []: conn.autocommit = True cur.execute(DB_NAME) conn.autocommit = False else: print(‘{} is exist‘.format(DATABASE_NAME)) cur.close() conn.close()
行吧,到此位置,功能实现~我们下次再见,如果你觉得对你有帮助,麻烦点个“推荐”,谢谢~
当然,如果你有更优雅的办法,请在下面留言,谢谢
参考
使用python创建Postgres数据库:https://www.e-learn.cn/content/wangluowenzhang/448331
PostgreSQL 学习之使用psycopg2 操作之数据库不存在才创建
标签:自己的 奇葩 需要 功能 而且 思路 mysql 很多 游标
本文系统来源:https://www.cnblogs.com/yungiu/p/10983792.html
内容总结
以上是互联网集市为您收集整理的PostgreSQL 学习之使用psycopg2 操作之数据库不存在才创建全部内容,希望文章能够帮你解决PostgreSQL 学习之使用psycopg2 操作之数据库不存在才创建所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。