Réglage de schéma pour toutes les requêtes de connexion dans psycopg2: mise en condition de course lors de la configuration de search_path

Notre système est en cours d'exécution sur Ubuntu, python 3.4, postgresql 9.4.x et psycopg2.

Nous (dans le meuble de style, partagée entre l' dev, test et prod environnements à l'aide de schémas. J'ai créer une méthode pratique pour créer des connexions à notre base de données. Il utilise json fichiers de configuration de connexion afin de créer la chaîne de connexion. Je veux configurer la connexion à l'utilisation d'un schéma pour toutes les requêtes suivantes en utilisant le retour de la connexion. Je ne veux pas que mes requêtes sont codées en dur schémas, parce que nous devrions être en mesure de facilement basculer entre eux en fonction de si on est en développement, le test ou la phase de production/environnement.

Actuellement la méthode de convenance se présente comme suit:

def connect(conn_config_file = 'Commons/config/conn_commons.json'):
    with open(conn_config_file) as config_file:    
        conn_config = json.load(config_file)

    conn = psycopg2.connect(
        "dbname='" + conn_config['dbname'] + "' " +
        "user='" + conn_config['user'] + "' " +
        "host='" + conn_config['host'] + "' " +
        "password='" + conn_config['password'] + "' " +
        "port=" + conn_config['port'] + " "
    )
    cur = conn.cursor()
    cur.execute("SET search_path TO " + conn_config['schema'])

    return conn

Il fonctionne très bien tant que vous lui donnez temps pour exécuter l'ensemble search_path requête. Malheureusement, si je suis trop rapide à l'exécution d'une requête suivante une condition de concurrence se produit lorsque le search_path n'est pas définie. J'ai essayé de forcer l'exécution avec faire un conn.commit() avant la return conn, cependant, cela réinitialise le search_path le schéma par défaut postgres, afin de ne pas utiliser, disons, prod. Suggestions à la base de données ou de l'application de la couche est préférable, cependant, je sais qu'on pourrait probablement résoudre ce au niveau de l'OS aussi, des suggestions dans ce sens sont également accueillis.

Un exemple json fichier de configuration se présente comme suit:

{
    "dbname": "thedatabase",
    "user": "theuser",
    "host": "localhost",
    "password": "theusers_secret_password",
    "port": "6432",
    "schema": "prod"
}

Toute suggestion est très apprécié.

Peut-être attendre une seconde avant de se retourner? import time; time.sleep(1)
Je ne peux pas croire que je suis en train de faire, mais je vais aller pour votre réponse. Si vous souhaitez que le crédit que vous pouvez poster une réponse et je vais l'accepter.
Voulez-vous dire, c'est assez inélégant? Oui, n'est qu'une solution de contournement
Pouvez-vous poster une partie de code qui illustre la condition de la course? Étant donné que vous avez une connexion unique et les requêtes sont exécutées de manière séquentielle, il ne devrait pas y avoir de possibilité d'une condition de concurrence dans le code que vous avez posté. Si je l'ai copier/coller votre code, coder en dur les paramètres de connexion à un local Postgres exemple de la mine, et ensuite ajouter une requête SHOW search_path, le résultat de SET est visible.
Il est impossible d'obtenir une condition de concurrence dans une seule connexion. Comme son nom l'indique, il a besoin d'au moins deux concurrents.

OriginalL'auteur André C. Andersen | 2015-09-27