List of vertices per face
This way starts with mesh loops rather than vertices, because, although it seems true, I can find no guarantee that polygons list their vertices in order with respect to their normals. (Maybe someone can correct me on that.) So there's a bit of extra wrangling. 

As is typical of 3D applications, loops are ordered anticlockwise with respect to forward-facing normals, so have to be reversed, and the (formerly) last element repeated.

import bpy

me = bpy.context.object.data

# per-poly lists of loop indices
pli = (p.loop_indices for p in me.polygons)
# .. to per-poly lists of vertex indices
pvi = ([me.loops[l].vertex_index for l in ll] for ll in pli)
# ..to per-poly lists of vertices
p_verts = ([me.vertices[id] for id in idl] for idl in pvi)

# floating point precision
prec = 2

co_lists =[]

for v_list in p_verts:
    co_str = '    (('
    co_strs = []
    for v in [*v_list[::-1],v_list[-1]]:
        co_strs.append(f'{v.co[0]: .{prec}f} '
                       f'{v.co[1]: .{prec}f} '
                       f'{v.co[2]: .{prec}f}')
    co_str += ', '.join(co_strs)
    co_str += '))'
    co_lists.append(co_str)

DBstr =  "SELECT ST_GeomFromText('POLYHEDRALSURFACE Z(\n"    
DBstr += ",\n".join(co_lists)
DBstr += " )');"


print(DBstr) 


If nothing else, maybe you can pick the slice  [::-1]... [-1] out of it for reversing and repeating your elements, and/or the str.join() for dealing with your extra terminal comma.