PostgreSQL へのログイン ロールの追加

Standard または Advancedのライセンスで利用可能。

PostgreSQL ではロールを使用して、データベース クラスターおよびデータベースにログインします。個々のユーザーは、ログイン ロールと呼ばれます。ログイン ロールがジオデータベース内のオブジェクトを所有する場合は、そのデータベースにスキーマも作成する必要があります。ArcGIS で PostgreSQL を使用する場合、スキーマにはロールと同じ名前を付ける必要があります。また、ログイン ロールによって所有されていなければなりません。

[データベース ユーザーの作成 (Create Database User)] ツールを使用して、テーブルとフィーチャクラスを作成する権限を持つログイン ロールを追加できます。このツールでは、PostgreSQL データベース クラスターにログイン ロールを作成し、ユーザーに対応するスキーマを指定したデータベースに作成し、新しいスキーマに対する usage 権限を public に付与します。

スキーマを所有していないためジオデータベース内にオブジェクトを作成できないログイン ロールを作成する場合、pgAdmin や PL/pgSQL のような PostgreSQL クライアント アプリケーションを使用して、PostgreSQL データベース クラスターにロールを作成します。

グループ ロールを作成して、ログイン ロールを追加することもできます。その後、グループに追加されているすべてのログイン ロールに適用される権限をグループに対して付与することができます。グループ ロールを作成するには、[ロールの作成 (Create Role)] ツールまたはスクリプトを使用するか、SQL を使用します。

メモ:

グループの場合でも、グループ内のログイン ロールがジオデータベース内のオブジェクトを所有するときは、それぞれのログイン ロールに対応するスキーマを作成する必要があります。グループ ロール用のスキーマを作成することはできません。

データベース オブジェクトを作成できるユーザーの追加

ArcGIS Desktop から [データベース ユーザーの作成 (Create Database User)] ツールを実行するか、Python スクリプトでこのツールを呼び出して、テーブル、フィーチャクラス、およびビューを作成する権限を持つデータベース ユーザーを作成できます。

[データベース ユーザーの作成 (Create Database User)] ツールを実行するには、スーパーユーザー ステータスを持つロールを使用してデータベースに接続する必要があります。

データベース ユーザーの作成 (Create Database User) ツールの使用

  1. ArcGIS Desktop クライアントを起動します。
  2. PostgreSQL のスーパーユーザー権限を持つロールを使用して、データベースまたはジオデータベースに接続します。
  3. [データベース ユーザーの作成 (Create Database User)] ツールを開きます。

    このツールは、[データ管理] ツールボックスの [ジオデータベース管理] ツールセットにあります。

  4. [入力データベース接続] で、データベース接続を指定します。
  5. ツールが作成するログイン ロールとスキーマの名前を入力します。
  6. データベース ユーザーのパスワードを入力します。
  7. このユーザーをメンバーにするグループ ロールがすでに存在する場合は、そのロールを指定します。
  8. [OK] (ArcMap) または [実行] (ArcGIS Pro) をクリックします。

Python スクリプトの実行

ユーザーの作成をスクリプト化するには、以下の手順に従います。

  1. ArcGIS クライアント コンピューター上でテキスト ファイルを作成し、そのファイルに以下のスクリプトをコピーします。

    """
    Name: create_database_user.py
    Description: Provide connection information to a database user.
    Type create_database_user.py -h or create_database_user.py --help for usage
    """
    
    # Import system modules
    import arcpy
    import os
    import optparse
    import sys
    
    
    # Define usage and version
    parser = optparse.OptionParser(usage = "usage: %prog [Options]", version="%prog 1.0 for 10.1 release")
    
    #Define help and options
    parser.add_option ("--DBMS", dest="Database_type", type="choice", choices=['SQLSERVER', 'ORACLE', 'POSTGRESQL', ''], default="", help="Type of enterprise DBMS:  SQLSERVER, ORACLE, or POSTGRESQL.")                   
    parser.add_option ("-i", dest="Instance", type="string", default="", help="DBMS instance name")
    parser.add_option ("-D", dest="Database", type="string", default="none", help="Database name:  Not required for Oracle")
    parser.add_option ("--auth", dest="Account_authentication", type ="choice", choices=['DATABASE_AUTH', 'OPERATING_SYSTEM_AUTH'], default='DATABASE_AUTH', help="Authentication type options (case-sensitive):  DATABASE_AUTH, OPERATING_SYSTEM_AUTH.  Default=DATABASE_AUTH")
    parser.add_option ("-U", dest="Dbms_admin", type="string", default="", help="DBMS administrator user")
    parser.add_option ("-P", dest="Dbms_admin_pwd", type="string", default="", help="DBMS administrator password")
    parser.add_option ("--utype", dest="user_type", type ="choice", choices=['DATABASE_USER', 'OPERATING_SYSTEM_USER'], default='DATABASE_USER', help="Authentication type options (case-sensitive):  DATABASE_USER, OPERATING_SYSTEM_USER.  Default=DATABASE_USER")
    parser.add_option ("-u", dest="dbuser", type="string", default="", help="database user name")
    parser.add_option ("-p", dest="dbuser_pwd", type="string", default="", help="database user password")
    parser.add_option ("-r", dest="role", type="string", default="", help="role to be granted to the user")
    parser.add_option ("-t", dest="Tablespace", type="string", default="", help="Tablespace name")
    # Check if value entered for option
    try:
    	(options, args) = parser.parse_args()
    
    	#Check if no system arguments (options) entered
    	if len(sys.argv) == 1:
    		print "%s: error: %s\n" % (sys.argv[0], "No command options given")
    		parser.print_help()
    		sys.exit(3)
    
    	#Usage parameters for spatial database connection
    	database_type = options.Database_type.upper()
    	instance = options.Instance
    	database = options.Database.lower()	
    	account_authentication = options.Account_authentication.upper()
    	dbms_admin = options.Dbms_admin
    	dbms_admin_pwd = options.Dbms_admin_pwd
    	dbuser = options.dbuser
    	dbuser_pwd = options.dbuser_pwd	
    	tablespace = options.Tablespace
    	user_type = options.user_type
    	role = options.role
    
    	
    	if (database_type == "SQLSERVER"):
    		database_type = "SQL_SERVER"
    	
    	if( database_type ==""):	
    		print(" \n%s: error: \n%s\n" % (sys.argv[0], "DBMS type (--DBMS) must be specified."))
    		parser.print_help()
    		sys.exit(3)		
    	
    	if(database_type == "SQL_SERVER"):
    		if( account_authentication == "DATABASE_AUTH" and dbms_admin == ""):
    			print("\n%s: error: %s\n" % (sys.argv[0], "DBMS administrator must be specified with database authentication"))
    			sys.exit(3)
    		if( account_authentication == "OPERATING_SYSTEM_AUTH" and dbms_admin != ""):
    			print("\nWarning: %s\n" % ("Ignoring DBMS administrator specified when using operating system authentication..."))
    	else:		
    		if( dbuser.lower() == ""):
    			print("\n%s: error: %s\n" % (sys.argv[0], "Database user must be specified."))
    			sys.exit(3)		
    		if( dbms_admin == ""):
    			print("\n%s: error: %s\n" % (sys.argv[0], "DBMS administrator must be specified!"))
    			sys.exit(3)
    
    	if ( user_type == "DATABASE_USER" and (dbuser =="" or dbuser_pwd =="")):
    		print(" \n%s: error: \n%s\n" % (sys.argv[0], "To create database authenticated user, user name and password must be specified!"))
    		parser.print_help()
    		sys.exit(3)	
    
    	# Get the current product license
    	product_license=arcpy.ProductInfo()
    	
    	# Checks required license level
    	if product_license.upper() == "ARCVIEW" or product_license.upper() == 'ENGINE':
    		print("\n" + product_license + " license found!" + "  Creating a user in an enterprise geodatabase or database requires an ArcGIS Desktop Standard or Advanced, ArcGIS Engine with the Geodatabase Update extension, or ArcGIS Server license.")
    		sys.exit("Re-authorize ArcGIS before creating a database user.")
    	else:
    		print("\n" + product_license + " license available!  Continuing to create...")
    		arcpy.AddMessage("+++++++++")
    
    	# Local variables
    	instance_temp = instance.replace("\\","_")
    	instance_temp = instance_temp.replace("/","_")
    	instance_temp = instance_temp.replace(":","_")
    	Conn_File_NameT = instance_temp + "_" + database + "_" + dbms_admin   
    
    	if os.environ.get("TEMP") == None:
    		temp = "c:\\temp"	
    	else:
    		temp = os.environ.get("TEMP")
    	
    	if os.environ.get("TMP") == None:
    		temp = "/usr/tmp"		
    	else:
    		temp = os.environ.get("TMP")  
    
    	Connection_File_Name = Conn_File_NameT + ".sde"
    	Connection_File_Name_full_path = temp + os.sep + Conn_File_NameT + ".sde"
    	
    	# Check for the .sde file and delete it if present
    	arcpy.env.overwriteOutput=True
    	if os.path.exists(Connection_File_Name_full_path):
    		os.remove(Connection_File_Name_full_path)
    
    	try:
    		print("\nCreating Database Connection File...\n")
    		# Process: Create Database Connection File...
    		# Usage:  out_file_location, out_file_name, DBMS_TYPE, instnace, database, account_authentication, username, password, save_username_password(must be true)
    		#arcpy.CreateDatabaseConnection_management(temp , Connection_File_Name, database_type, instance, database, account_authentication, dbms_admin, dbms_admin_pwd, "TRUE")
    		arcpy.CreateDatabaseConnection_management(out_folder_path=temp, out_name=Connection_File_Name, database_platform=database_type, instance=instance, database=database, account_authentication=account_authentication, username=dbms_admin, password=dbms_admin_pwd, save_user_pass="TRUE")
    	        for i in range(arcpy.GetMessageCount()):
    			if "000565" in arcpy.GetMessage(i):   #Check if database connection was successful
    				arcpy.AddReturnMessage(i)
    				arcpy.AddMessage("\n+++++++++")
    				arcpy.AddMessage("Exiting!!")
    				arcpy.AddMessage("+++++++++\n")
    				sys.exit(3)            
    			else:
    				arcpy.AddReturnMessage(i)
    				arcpy.AddMessage("+++++++++\n")
    
    		print("Creating database user...\n")
    		arcpy.CreateDatabaseUser_management(input_workspace=Connection_File_Name_full_path, user_authentication_type=user_type, user_name=dbuser, user_password=dbuser_pwd, role=role, tablespace_name=tablespace)
    		for i in range(arcpy.GetMessageCount()):
    			arcpy.AddReturnMessage(i)
    		arcpy.AddMessage("+++++++++\n")
    	except:
    		for i in range(arcpy.GetMessageCount()):
    			arcpy.AddReturnMessage(i)
    			
    #Check if no value entered for option	
    except SystemExit as e:
    	if e.code == 2:
    		parser.usage = ""
    		print("\n")
    		parser.print_help()   
    		parser.exit(2)

    ArcGIS Desktop (Standard または Advanced)、ArcGIS Server (Standard または Advanced)、または ArcGIS Engine と Geodatabase Update エクステンションがインストールされているコンピューターからスクリプトを実行できます。

  2. *.py 拡張子を付けてファイルを保存します。
  3. 使用している PostgreSQL データベース クラスターと作成するログイン ロールに固有のオプションと情報を指定してスクリプトを実行します。

    以下の例では、Microsoft Windows サーバーから実行しており、スクリプト名は create_database_user.py です。データベース認証ログイン ロール (geodata) を PostgreSQL データベース クラスター pgdb7 に作成し、それに対応するスキーマをデータベース gisdata に作成します。このユーザーはグループ ロールに追加されません。

    create_database_user.py --DBMS POSTGRESQL -i pgdb7 -D gisdata -U postgres -P $hHhH --utype DATABASE_USER -u geodata -p 0wn1t

    次の例では、Linux コンピューター上でスクリプトを実行しています。

    ./create_database_user.py --DBMS POSTGRESQL -i pgdb7 -D gisdata -U postgres -P $hHhH --utype DATABASE_USER -u geodata -p 0wn1t

    ヒント:

    構文ヘルプを取得するには、コマンド プロンプトに「-h」または「--help」と入力します。

これで、テーブルを作成する権限を持つユーザーがデータベースに作成されました。

データを表示および編集するログインの作成

SQL を使用して、データを作成しないユーザーのログイン ロールを作成できます。ただし、PostgreSQL のジオデータベースで実行する場合は、パブリック グループまたは特定のユーザーが、一時テーブルを作成する権限を持っていることを確認してください。

これらのユーザーへの個別のデータセットに対する権限の付与を簡単にするために、ログイン グループを作成することもできます。

ロールの作成

以下では、データ権限管理を簡単にするために psql を使用してグループ ロールを作成する手順、およびグループ ロールに所属するログイン ロールを作成する手順について説明します。

  1. データベース クラスターに他のロールを作成する権限を持つユーザーとして psql にログインします。これには、スーパーユーザー ステータスを持つログイン、または createrole 権限が付与されているログインを使用できます。
  2. はじめに、create role コマンドを使用して、データセットを編集できるユーザー (editors) とデータの表示のみが可能なユーザー (viewers) の 2 つのログイン グループを作成します。

    CREATE ROLE editors 
    NOSUPERUSER NOCREATEDB NOCREATEROLE NOINHERIT;
    CREATE ROLE viewers
    NOSUPERUSER NOCREATEDB NOCREATEROLE NOINHERIT;

  3. 次に、editors グループのメンバーになるログイン ロールを作成します。

    この例では、暗号化パスワードを使用して、ログイン ロール (editor1) を作成します。このロールはスーパーユーザー ステータスを持っていないので、データベースを作成できず、ロールをデータベース クラスターに作成できません。ただし、このロールはグループ ロール editors のメンバーになっているため、このグループ ロールから権限を継承します。

    CREATE ROLE editor1 LOGIN 
    ENCRYPTED PASSWORD 'sooper.secret' 
    NOSUPERUSER NOCREATEDB NOCREATEROLE INHERIT IN ROLE editors;
    ログイン ロール名を変更し、ステートメントを再び実行して、ジオデータベースのデータを編集できるその他のログイン ロールを作成します。

  4. 次に、viewers グループのメンバーになるログイン ロールを作成します。

    この例では、暗号化パスワードを使用して、ログイン ロール (reader1) を作成します。このロールはスーパーユーザー ステータスを持っていないので、データベースを作成できず、ロールをデータベース クラスターに作成できません。ただし、このロールはグループ ロール viewers のメンバーになっているため、このグループ ロールから権限を継承します。

    CREATE ROLE reader1 LOGIN 
    ENCRYPTED PASSWORD 'almostas.secret' 
    NOSUPERUSER NOCREATEDB NOCREATEROLE INHERIT IN ROLE viewers;
    ログイン ロール名を変更し、ステートメントを再び実行して、ジオデータベースのデータを表示する権限のみを持つその他のログイン ロールを作成します。

  5. geodata スキーマに対する usage 権限を、各ログイン グループに付与します。

    editors および viewers のメンバーは、usage 権限によって geodata スキーマのデータにアクセスできます。USAGE 権限がなければ、geodata の各データセットに対する権限を viewers および editors グループ ロールのメンバーに付与することはできません。

    GRANT USAGE ON SCHEMA geodata TO editors;
    GRANT USAGE ON SCHEMA geodata TO viewers;
  6. ジオデータベース用のこれらのログインを作成する場合、および、すべてのユーザーが sde スキーマに対する usage 権限を持つことがないように sde スキーマ権限を変更した場合、sde スキーマに対する usage 権限を editors および viewers グループに付与します。
    GRANT USAGE ON SCHEMA sde TO editors;
    GRANT USAGE ON SCHEMA sde TO viewers;

これで、データを編集する 1 つ以上のユーザーおよびデータを表示する 1 つ以上のユーザーがデータベースに作成されました。

データベースまたはジオデータベースにデータセットが存在している場合、データセットの所有者は、データセットに対する select 権限を viewers グループに付与し、データセットに対する selectinsertupdate、および delete 権限を editors グループに付与することができます。手順については、「データセット権限の付与と取り消し」をご参照ください。