sql

package
v1.1.35 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 26, 2024 License: Apache-2.0 Imports: 12 Imported by: 14

Documentation

Overview

Package sql implements Input/Output for SQL. One can use sql to create a new table from a query. This is similar to the ClickHouse CREATE MATERIALIZED VIEW statement but there is no trigger to update the output table if the input changes.

There are three approaches to creating a new ClickHouse table:

  • Direct ClickHouse insertion. Use sql Reader.Insert to issue an Insert query with Reader.SQL as the source.

  • Values insertion. Use sql Writer.Insert to issue an Insert query using VALUES. The values are created by sql Writer writing values from a reader. Although the source can be a sql.Reader, more commonly one would expect it to be a file.Reader.

  • clickhouse-client insert. Use a file Writer.Insert to create a CSV file and then issue a shell command to run the clickhouse-client to insert the file.

Before any of these approaches are used, the TableDef.CreateTable() can be used to create the destination table.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func Wrtrs

func Wrtrs(table string, nWrtr int, conn *chutils.Connect) (wrtrs []chutils.Output, err error)

Wrtrs creates an array of writers suitable for chutils.Concur

Types

type Reader

type Reader struct {
	SQL      string // SQL is the SELECT string.  It does not have an INSERT
	RowsRead int    // RowsRead is the number of rows read so far
	Name     string // Name is the name of the output table created by Insert()
	// contains filtered or unexported fields
}

Reader implements chutils.Input interface.

func NewReader

func NewReader(sqlStr string, conn *chutils.Connect) *Reader

NewReader creates a new reader.

func (*Reader) Close

func (rdr *Reader) Close() error

Close closes the result set

func (*Reader) CountLines

func (rdr *Reader) CountLines() (numLines int, err error)

CountLines returns the number of rows in the result set.

func (*Reader) Init

func (rdr *Reader) Init(key string, engine chutils.EngineType) (err error)

Init initializes Reader.TableDef by looking at the output of the query. if key is empty, it defaults to the first field.

func (*Reader) Insert

func (rdr *Reader) Insert() error

Insert executes Reader.SQL and inserts the result into Reader.Name

func (*Reader) Materialize added in v1.1.28

func (rdr *Reader) Materialize(orderBy string) error

func (*Reader) Read

func (rdr *Reader) Read(nTarget int, validate bool) (data []chutils.Row, valid []chutils.Valid, err error)

Read reads nTarget rows. If nTarget == 0, the entire result set is returned.

If validation == true:

  • The data is validated according to the rules in rdr.TableSpec.
  • The results are returned as the slice valid.
  • data is returned with the fields appropriately typed.

If validation == false:

  • data is returned with the fields appropriately typed.
  • The return slice valid is nil

err is io.EOF at the end of the record set

func (*Reader) Reset

func (rdr *Reader) Reset() error

Reset resets the result set. The next read returns the first record.

func (*Reader) Seek

func (rdr *Reader) Seek(lineNo int) error

Seek moves to the lineNo record of the result set. The next read will start there.

func (*Reader) TableSpec

func (rdr *Reader) TableSpec() *chutils.TableDef

type Writer

type Writer struct {
	Table string // Table is the output table
	// contains filtered or unexported fields
}

Writer implements chutils.Output

func NewWriter

func NewWriter(table string, conn *chutils.Connect) *Writer

NewWriter creates a new SQL writer

func (*Writer) Close

func (wtr *Writer) Close() error

Close closes the work on the Values so far--that is, it empties the buffer.

func (*Writer) EOL

func (wtr *Writer) EOL() rune

EOL returns 0. This method is needed by chutils.Export.

func (*Writer) Insert

func (wtr *Writer) Insert() error

Insert executes an Insert query -- the values must have been built using Writer.Write

func (*Writer) Name

func (wtr *Writer) Name() string

Name returns the name of the table created by Insert.

func (*Writer) Separator

func (wtr *Writer) Separator() rune

Separator returns a comma rune. This method is needed by chutils.Export.

func (*Writer) Text added in v1.1.2

func (wtr *Writer) Text() string

Text returns the string delimiter

func (*Writer) Write

func (wtr *Writer) Write(b []byte) (n int, err error)

Write writes the byte slice to Writer.hold. The byte slice is a single row of the output

Example

This example reads from a file.Reader and writes to ClickHouse using a sql.Writer

/*
	/home/test/data/zip_data.csv:
	id,zip,value
	1A34,90210,20.8
	1X88,43210,19.2
	1B23,77810,NA
	1r99,94043,100.4
	1x09,hello,9.9
*/,9.9
*/

const inFile = "/home/will/tmp/zip_data.csv" // source data
const table = "testing.values"               // ClickHouse destination table
var con *chutils.Connect
con, err := chutils.NewConnect("127.0.0.1", "tester", "testGoNow", clickhouse.Settings{})
if err != nil {
	panic(err)
}
defer func() {
	if con.Close() != nil {
		panic(err)
	}
}()
f, err := os.Open(inFile)
if err != nil {
	panic(err)
}
rdr := file.NewReader(inFile, ',', '\n', '"', 0, 1, 0, f, 50000)
defer func() {
	if rdr.Close() != nil {
		panic(err)
	}
}()
if e := rdr.Init("zip", chutils.MergeTree); e != nil {
	panic(err)
}
if e := rdr.TableSpec().Impute(rdr, 0, .95); e != nil {
	panic(e)
}

// Specify zip as FixedString(5) with a missing value of 00000
_, fd, err := rdr.TableSpec().Get("zip")
if err != nil {
	panic(err)
}
// zip will impute to int if we don't make this change
fd.ChSpec.Base = chutils.ChFixedString
fd.ChSpec.Length = 5
fd.Missing = "00000"
legal := []string{"90210", "43210", "77810", "94043"}
fd.Legal.Levels = legal

// Specify value as having a range of [0,30] with a missing value of -1.0
_, fd, err = rdr.TableSpec().Get("value")
if err != nil {
	panic(err)
}
fd.Legal.HighLimit = 30.0
fd.Legal.LowLimit = 0.0
fd.Missing = -1.0

rdr.TableSpec().Engine = chutils.MergeTree
rdr.TableSpec().Key = "id"
if err = rdr.TableSpec().Create(con, table); err != nil {
	panic(err)
}

wrtr := NewWriter(table, con)
if err = chutils.Export(rdr, wrtr, 0, false); err != nil {
	panic(err)
}

qry := fmt.Sprintf("SELECT * FROM %s", table)

res, err := con.Query(qry)
if err != nil {
	panic(err)
}
defer func() {
	if res.Close() != nil {
		panic(err)
	}
}()
for res.Next() {
	var (
		id    string
		zip   string
		value float64
	)
	if res.Scan(&id, &zip, &value) != nil {
		panic(err)
	}
	fmt.Println(id, zip, value)
}
Output:

1A34 90210 20.8
1B23 77810 -1
1X88 43210 19.2
1r99 94043 -1
1x09 00000 9.9

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL