Psycopg2 PostgreSQL database operations using the learning does not only exist to create

Loud tell me if I was two title "of" Give brought in? ? Manual funny

demand

Own a piece of software GitHub address , about PostgreSQL has been set to run automatically created after the sequence table and function, but still want to manually create the database, inconvenient, and want to use the same method to create a sequence table, to automatically create the database

process

DDL statements are as follows:

DB_NAME = """
CREATE DATABASE if not exists {};

ALTER DATABASE {} OWNER TO postgres;
""".format(DATABASE_NAME, DATABASE_NAME)
DDL statements will reportedly found a syntax error
psycopg2.ProgrammingError: syntax error at or near "not"
LINE 2: CREATE DATABASE if not exists test_classs;

And create a sequence table when no problem ah (I use a delete function after creation), how is this being given? Principle to run successfully, then realize the function, I put "if not exists" to be removed, the result was given:

psycopg2.InternalError: CREATE DATABASE cannot run inside a transaction block

You can not create a database in a transaction block, it probably means that this insecurity, Baidu plus Google, there are two ways:

1. ISOLATION_LEVEL_AUTOCOMMIT in psycopg2 extensions, the principle is to make the connection does not start when issuing commands to any transaction, see the constant name, which literally means is automatically submitted, and do not need to commit () or rollback () such as:

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. Let autocommit attribute automatic submission mode, the connection is using the connection object, such as:

Import psycopg2 

CON = psycopg2.connect (...) 
con.autocommit = True 

CUR = con.cursor () 
cur.execute ( ' the CREATE DATABASE {}; ' .format (db_name)) 
cur.close () 
# If not connected off, back to the required properties of the connection object autocommit 
con.autocommit = False
 # If the connection is closed, it is not necessary to perform the above line 
# con.close ()

But when I run, or encounter another error:

psycopg2.InternalError: CREATE DATABASE cannot be executed from a function or multi-command string

Literally speaking, is not created in the database function, and can not create a database in a string of multi-command, the function is useless to me, is the only multi-line commands, and looked at his DDL statements, he found himself copy the DDL statements to create the tables section a little more. . From the most simple to start it, after all these above two examples are not the problem, the DDL statement read:

DB_NAME = """
CREATE DATABASE {};
""".format(DATABASE_NAME)

Run again, although there is a Diudiu slow, but still created a success, but here, I recommend using the second method, because of the simple, no need to import this long constants, and very easy to control, such as the following requirements, create the first database, create a second database (how would there be such wonderful work requirements, ha ha, are for illustrative convenience)

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()

See, you need to import two very long variable names, of course, at the prompt IDE, so that in fact does not bother, but I always feel like this is not very elegant, after all, Python, not how elegant the line? So we can use another way:

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()

The effect is the same, saw that it was not a lot of comfortable?

Okay, now we can create a database, then how to achieve if there is no creation, there is no deal with it?

Since it can not be like 'MySQL' as used 'if not exists' to create the database, you can only change the other way around, first check to see if the database exists, if it does not exist then create the settings automatically submitted, if there is, it is not treated, excuse me? This is for the idea yet? Ahem. . Well, the idea has not changed, but the process is implemented in code that is. . Specific code as follows:

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()

 

Note that this SQL statement behind ALL_DB_NAME conditions placeholders {} must be quoted, otherwise it will report column "test_class" does not exist error

Test it, it looks like there is no problem, then switch to a non-existent database look, and sure enough, I did not think so simple. .

    conn.autocommit = True
psycopg2.ProgrammingError: set_session cannot be used inside a transaction

Baidu a bit, did not find the answer, but according to the literal meaning, certainly, and matters relating to, first try one of the most stupid way is the query log query results, and then the cursor and connections are closed, and then create a new connection the new cursor, according to the results to create a database, or no treatment and found no problems, although I feel strange, but also very happy, just when you want to park on the blog Write down solutions, and suddenly thought, the the last to be submitted after the inquiry is not about to OK? Quickly by their own stupid to cry, which is why I played so many words, not directly on the reason code, which is the lack of experience, but also the lack of knowledge database, blush, directly on the bar code, in fact, add one line of code solved.

result

 

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()

 

 

 

Okay, this location, function realization - we see you next time, if you feel that you have to help a trouble spot "recommended", thank you ~

Of course, if you have a more elegant solution, please leave a comment below, thank you

 

reference

Creating Postgres database using python: https: //www.e-learn.cn/content/wangluowenzhang/448331

 

 

Guess you like

Origin www.cnblogs.com/yungiu/p/10983792.html