Je souhaite créer une table gérée avec un emplacement sur AWS S3 via spark sql, mais si je spécifie l'emplacement, cela crée une table EXTERNAL même si je n'ai pas spécifié ce mot clé.
CREATE TABLE IF NOT EXISTS database.tableOnS3(name string) LOCATION 's3://mybucket/';
Pourquoi impliquent-ils un mot-clé EXTERNAL ici ...
Si j'exécute cette requête dans la console Hive, cela crée une table gérée, alors comment faire la même chose dans spark?
3 Réponses :
Voir documents Hive connaît fondamentalement deux types de tables différents:
Géré (interne)
Externe
Tables gérées : une table gérée est stockée sous le propriété de chemin hive.metastore.warehouse.dir, par défaut dans un dossier chemin similaire à /user/hive/warehouse/databasename.db/tablename/. Le l'emplacement par défaut peut être remplacé par la propriété location pendant création de table. Si une table ou une partition gérée est supprimée, les données et les métadonnées associées à cette table ou partition sont supprimées. Si l'option PURGE n'est pas spécifiée, les données sont déplacées vers un dossier corbeille pour une durée définie.
Utilisez des tables gérées lorsque Hive doit gérer le cycle de vie de la table, ou lors de la génération de tables temporaires.
Tables externes : une table externe décrit les métadonnées / schémas sur fichiers externes. Les fichiers de table externes sont accessibles et gérés par processus en dehors de Hive. Les tables externes peuvent accéder aux données stockées dans sources telles que Azure Storage Volumes (ASV) ou emplacements HDFS distants. Si la structure ou le partitionnement d'une table externe est modifié, un L'instruction nom_table MSCK REPAIR TABLE peut être utilisée pour actualiser les métadonnées informations.
Utilisez des tables externes lorsque les fichiers sont déjà présents ou à distance emplacements, et les fichiers doivent rester même si la table est supprimée.
Conclusion:
puisque vous utilisez l'emplacement s3 qui est externe à son affichage comme ça.
En outre, vous voulez comprendre comment le code fonctionne voir CreateTableLikeCommand
em > : dans ce val tblType = if (location.isEmpty) CatalogTableType.MANAGED else CatalogTableType.EXTERNAL
est l'endroit où il décide dynamiquement ...
/** * A command to create a table with the same definition of the given existing table. * In the target table definition, the table comment is always empty but the column comments * are identical to the ones defined in the source table. * * The CatalogTable attributes copied from the source table are storage(inputFormat, outputFormat, * serde, compressed, properties), schema, provider, partitionColumnNames, bucketSpec. * * The syntax of using this command in SQL is: * {{{ * CREATE TABLE [IF NOT EXISTS] [db_name.]table_name * LIKE [other_db_name.]existing_table_name [locationSpec] * }}} */ case class CreateTableLikeCommand( targetTable: TableIdentifier, sourceTable: TableIdentifier, location: Option[String], ifNotExists: Boolean) extends RunnableCommand { override def run(sparkSession: SparkSession): Seq[Row] = { val catalog = sparkSession.sessionState.catalog val sourceTableDesc = catalog.getTempViewOrPermanentTableMetadata(sourceTable) val newProvider = if (sourceTableDesc.tableType == CatalogTableType.VIEW) { Some(sparkSession.sessionState.conf.defaultDataSourceName) } else { sourceTableDesc.provider } // If the location is specified, we create an external table internally. // Otherwise create a managed table. val tblType = if (location.isEmpty) CatalogTableType.MANAGED else CatalogTableType.EXTERNAL val newTableDesc = CatalogTable( identifier = targetTable, tableType = tblType, storage = sourceTableDesc.storage.copy( locationUri = location.map(CatalogUtils.stringToURI(_))), schema = sourceTableDesc.schema, provider = newProvider, partitionColumnNames = sourceTableDesc.partitionColumnNames, bucketSpec = sourceTableDesc.bucketSpec) catalog.createTable(newTableDesc, ifNotExists) Seq.empty[Row] } }
Mise à jour: Si j'exécute cette requête dans la console hive, cela crée une table gérée, alors comment faire de même dans spark?
j'espère que vous utilisez le même emplacement local (pas un vpc différent) où hive et l'étincelle coexiste. si c'est le cas, définissez
spark.sql.warehouse.dir = hdfs: /// ... sur l'emplacement s3
en utilisant spark conf .... vous devrez peut-être définir l'accès les informations d'identification de la clé et de l'ID secret pour déclencher l'objet de configuration pour créer une session Spark.
Si j'utilise la console hive et que je fais de même, c'est créer une table gérée, c'est exactement ce que je veux faire dans spark. Ma question est donc de savoir comment faire cela?
ok où house dir est l'emplacement où il décide ... quand vous exécutez avec la ligne de commande c'est local où comme quand vous utilisez spark alors ce n'est pas local (externe). c'est la raison. essayez de définir l'emplacement de votre répertoire d'entrepôt sur l'emplacement s3 et voyez
merci pour l'aide, mais je sais de cette façon et malheureusement je ne peux pas le faire dans ma situation, car c'est un cluster de production et il est hébergé sur hdfs. Les travaux Spark doivent également lire à partir de hdfs, je ne peux donc pas simplement le définir dans les paramètres du travail
d'accord. si vous obtenez une solution élégante, veuillez la poster ici. Vous voulez voir quelles sont les alternatives pour cela.
changez le tableType en MANAGED une fois la table externe créée.
importer org.apache.spark.sql.catalyst.TableIdentifier import org.apache.spark.sql.catalyst.catalog.CatalogTableType
val identifier = TableIdentifier (yourTableName, Some (yourDatabaseName) spark.sessionState.catalog.alterTable (spark.sessionState.catalog.getTableMetadata (identifiant) .copy (tableType = CatalogTableType.MANAGED))
Votre réponse ne contient pas la déclaration nécessaire pour accomplir cela, ne répond pas au Q sur le mot-clé EXTERNAL et ne montre pas non plus comment accomplir cela dans Spark. Pensez à mettre à jour / améliorer votre réponse, vous pouvez le faire!
mis à jour ma réponse ...