Queremos enseñarte la mejor respuesta que hemos encontrado on line. Nosotros esperamos que te sea de utilidad y si puedes comentarnos algo que nos pueda ayudar a perfeccionar nuestra información puedes hacerlo..
Solución:
Agregar una tabla PostGIS a un mapa QGIS
En un complemento de QGIS, usaría QgsDataSourceURI de la API de pyqgis. Aquí hay un fragmento de un proyecto en el que trabajé.
La conexión a la base de datos está envuelta en una función. Todo lo que necesitas es db_params. La contraseña solo está codificada en base64; Ya que el pw no es un gran secreto y los usuarios donde trabajo no son hackers.
def get_dbparams(self):
# Get db connections params #
DB = 'somedb'
PORT = 5432
HOST = '11.22.333.44'
user = self.get_userrole()
if user == GrukosUser.READER:
db_params =
'dbname': DB,
'user': 'grukosreader',
'host': HOST,
'password': base64.b64decode('SDFADSASDFADF'),
'port': PORT
return db_params
elif user == GrukosUser.WRITER:
db_params =
'dbname': DB,
'user': 'grukoswriter',
'host': HOST,
'password': base64.b64decode('SDFGSGSDFGSDFGSDF'),
'port': PORT
return db_params
else:
return None
Obtenga los parámetros:
db = MyDb()
params = db.get_dbparams()
Establecer la fuente de datos:
uri = QgsDataSourceURI()
uri.setConnection(params['host'], str(params['port']), params['dbname'], params['user'], params['password'])
Si usa un filtro en la mesa sin geometría:
uri.setDataSource("myschema", "mytablename", None, "mycolumn=".format(myvalue))
Si usa un filtro en una mesa con una geometría:
uri.setDataSource("myschema", "mytablename", "mygeom", "mycolumn=".format(myvalue))
Si no hay filtro ni geometría:
uri.setDataSource("myschema", "mytablename", None)
Si no hay filtro ni geometría:
uri.setDataSource("myschema", "mytablename", "geom")
Si usa una vista espacial. Debe tener una columna única. Aquí llamado id:
uri.setDataSource("myschema", "mytablename", "geom", aKeyColumn='id')
uri.setKeyColumn('id')
Luego:
vlayer = QgsVectorLayer(uri.uri(), "mylayername", "postgres")
Verificar validez:
if not vlayer.isValid():
...
Agregar al mapa:
QgsMapLayerRegistry.instance().addMapLayer(vlayer, True)
Ningún mapa solo necesita obtener algunos datos de Postgres
Yo uso psycopg2 como:
def get_projectid(self, gkoid):
""" Use a PostgreSQL function to translate gkoid to projectid """
sql = 'SELECT myschema.mypgfunction();'.format(gkoid)
cur = self.execute_sql(sql)
rows_tuple = cur.fetchone()
projectid = rows_tuple[0]
return projekcid, sql
def execute_sql(self, sql, dict_cursor=True, print_sql=False):
""" Execute a SQL query
:param sql: SQL to be executed
:param dict_cursor: Flag indicating if cursor is a dict or not. Use false for scalar queries
:param print_sql: Flag indicating if sql is to be printet
:return: returns a cursor
"""
if print_sql: print sql
conn = psycopg2.connect(**self.get_dbparams())
if dict_cursor:
cur = conn.cursor(cursor_factory = psycopg2.extras.DictCursor)
else:
cur = conn.cursor()
try:
cur.execute(sql)
return cur
except psycopg2.DatabaseError, e:
print 'Some error '.format(e)
sys.exit(1)
finally:
pass
#TODO
#if conn:
# conn.close()
Inicio sesión
En algunos casos, un error en SQL bloqueará QGIS de una vez. Una forma de depuración es conectarse al QgsMessageLog. Lo envuelvo en una función como esta:
def enable_qgis_log(filename = 'D:gqis.log', haltApp = False, haltMsg = 'stop'):
""" Very useful when QGIS crashes on PGSQL error
:param filename: Filename and path for log file
:param haltApp: Halts the application with a modal dialog
:param haltMsg: Message to user when showing model stopping dialog
:rtype: None
"""
def write_log_message(message, tag, level):
with open(filename, 'a') as logfile:
logfile.write('tag(level): message'.format(tag=tag, level=level, message=message))
QgsMessageLog.instance().messageReceived.connect(write_log_message)
if haltApp:
QtGui.QMessageBox.information(None, GrukosAux.GRUKOS, "".format(haltMsg.encode('cp1252')), QtGui.QMessageBox.Ok)
Si conn
es su conexión de base de datos desde su código anterior, dispara su declaración sql de la siguiente manera:
c = conn.cursor()
c.execute('SELECT * FROM mytesttable')
c.fetchall()
Dónde fetchall()
devuelve una lista de tuplas que contienen los valores de columna de su SELECT
(implica que conoce su orden cuando SELECT
En g *
).
Tenga en cuenta que psycopg2
como un cliente de base de datos no confirma automáticamente los cambios de la base de datos cuando usa declaraciones como INSERT
o UPDATE
. En los últimos casos, tienes que terminar implícitamente tu declaración con
c.execute('COMMIT;')
Finalizando este artículo puedes encontrar las reseñas de otros administradores, tú además tienes el poder dejar el tuyo si lo crees conveniente.