Question

It would be nice to be able to use BigQuery via ODBC. I already use MySQL through ODBC, and this would let me switch to BigQuery as a drop-in replacement for MySQL for my Big Data tables.

Was it helpful?

Solution

Simba, an expert in ODBC (they have ODBC drivers for nearly every data source you can think of), has built an ODBC connector for BigQuery. You can download it for free (for Windows) from the BigQuery third party tools page here (scroll down to the bottom of the page). If you would prefer to use Linux, you can download the ODBC driver from Simba directly from here. Note that Simba does charge if you download from their site. Their driver may be more up-to-date and will include support.

A feature to note is that the Simba driver has the ability to translate standard SQL-92 compliant SQL into BigQUery's dialect of SQL. This can be useful if you want to use it as a drop-in replacement for a relational database. However, if you want to use the full features of BigQuery (nested data, shuffled JOIN / GROUP BY), you should turn this switch off to send queries directly.

Once you've installed the BigQuery ODBC driver and created a DSN (see Simba ODBC docs for a step-by-step guide to DSN creation), you'll want to start making ODBC queries. Here is a code sample that does this from C#. If you compile and run it, it will connect to BigQuery, run a simple query, and print the results.

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Odbc;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace BigQueryE2E
{
  /** 
   * Helper class to build an ODBC Connection to connect to a Simba 
   * BigQuery ODBC Driver.
   */
  class ConnectionBuilder {
    private String Dsn;
    private String Catalog;
    private String ExecCatalog;
    private bool UseNativeQuery;

    public ConnectionBuilder SetDsn(String dsn) { 
      Dsn = dsn; 
      return this; 
    }
    public ConnectionBuilder SetCatalog(String catalog) {
      Catalog = catalog; 
      return this; 
    }
    public ConnectionBuilder SetBillingCatalog(String catalog) {
      ExecCatalog = catalog;
      return this;
    }
    public ConnectionBuilder SetUseNativeQuery(bool nativeQuery) {
      UseNativeQuery = nativeQuery;
      return this;
    }

    public OdbcConnection Build() {
      if (Catalog == null || Dsn == null) {
        throw new ArgumentException("Missing required Connection setting");
      }

      StringBuilder connectionString = new StringBuilder();

      connectionString.AppendFormat("DSN={0}; Catalog={1};", Dsn, Catalog);
      if (ExecCatalog != null) {
        connectionString.AppendFormat("ExecCatalog={0};", ExecCatalog);
      }
      if (UseNativeQuery) {
        connectionString.Append("UseNativeQuery=1");
      }

      OdbcConnection conn = new OdbcConnection();
      conn.ConnectionString = connectionString.ToString();
      return conn;
    }
  }

  class Program {
    private static String Query = 
        "SELECT corpus, SUM(word_count) " + 
        "FROM samples.shakespeare " +
        "GROUP BY corpus";

    private static void PrintResults(OdbcDataReader reader) {
      for (int ii = 0; ii < reader.FieldCount; ii += 1) {
        System.Console.Write("{0}{1}",
            reader.GetName(ii),
            ii + 1 < reader.FieldCount ? "\t" : "\n");
      }
      while (reader.Read()) {
        for (int ii = 0; ii < reader.FieldCount; ii += 1) {
          System.Console.Write("{0}{1}",
              reader.GetValue(ii),
              ii + 1 < reader.FieldCount ? "\t" : "\n");
        }
      }
    }
    static void Main(string[] args) {
      OdbcConnection connection = new ConnectionBuilder()
          .SetDsn("bigquery1")
          .SetCatalog("publicdata")
          .SetBillingCatalog("bigquery-e2e")
          .Build();
      try {
        connection.Open();
        using (OdbcCommand command =  connection.CreateCommand()) {
          command.CommandText = Query;
          using (OdbcDataReader reader = command.ExecuteReader()) {
            PrintResults(reader);
          }
        }
      } catch (Exception ex) {
        System.Console.WriteLine("Error {0}: {1}",
          connection.State != ConnectionState.Open 
              ? "opening connection" : "executing query",
          ex);
      } finally {
        connection.Close();
      }
      System.Console.ReadKey();
    }
  }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top