gocql SELECT * не возвращает все столбцы

Я столкнулся с этим странным поведением, пытаясь реализовать некоторые счетчики для моего приложения. По сути, я сделал счетную таблицу примерно так:

CREATE TABLE stats_dev.log_counters (
  date text PRIMARY KEY,
  all counter
);

Затем у меня есть несколько конкретных типов сообщений, которые я тоже хочу посчитать, поэтому в приложении Go я изменяю таблицу, чтобы добавить столбец, которого раньше не было.

Мое приложение растет, и я начинаю иметь более 30 столбцов (не должно быть больше 50), и когда я хочу получить все эти счетчики, в результате отсутствуют некоторые столбцы.

query := s.Query(`SELECT * FROM `+_apiCountersTable+` WHERE date IN ?`, dates)
res, err := query.Iter().SliceMap()

Это возвращает мне что-то вроде 30 над 34 столбцами. Хотя, когда я делаю запрос на CQLSH:

cqlsh:stats_dev> SELECT * FROM api_counters WHERE date = 'total';

Я получаю правильный полный результат. Так:

  1. Это приходит из моего запроса, который должен быть другим?
  2. Может ли это быть из- за драйвера gocql?
  3. Эта модель совершенно глупая?

Мое временное решение состоит в том, чтобы выбрать имена столбцов из system.schema_columns table и to strings.Join () все это в мой запрос SELECT...

Большое спасибо за Вашу помощь.

2 ответа

Решение

Спасибо Энди за вашу помощь.

Сначала я подумал, что, учитывая то, что вы мне сказали, я бы лучше SELCT column_name на system.schema_columns иногда и обновлять его, когда я изменяю свой стол. Я бы тогда strings.join() колонны в моем SELECT FROM api_counters, Это сработало, но если бы у меня было 2 разных экземпляра, и один из них обновил бы схему, а другой получил бы запрос GET, этот еще не знал бы новый столбец.

А затем я перестроил свои идеи и обнаружил, что, очевидно, был другой способ сделать это, и я просто изменил эту схему: CREATE TABLE stats_dev.api_counters ( date text, description text, all counter, PRIMARY KEY (date, description) ); и я обновляю поле на основе описания, которое я ожидаю. Все идет нормально.

Я знал, что это определенно вариант 3: мой рисунок был не лучшим.

Я не знаком с библиотекой gocql, но, похоже, вы столкнулись с тем, что не представляете свои заявления и CASSANDRA-7910.

Всякий раз, когда запрос подготовлен (например, что делается в Select * из ___, где дата в?), Он отправляет запрос в cassandra, который отвечает метаданными столбца для этой таблицы, поэтому, когда вы получаете ответ на запрос от Кассандра, вы знаете, какие столбцы доступны для поиска. Похоже, gocql имеет функцию под названием Automatic query preparation который может рассматривать ваш запрос как подготовленное заявление.

Когда вы изменяете таблицу, подготовленный оператор не обновляется на вашей клиентской стороне, так что на самом деле единственный способ исправить это - представить ваш оператор (не уверен, что у вас есть такой уровень контроля со стороны gocql). Однако это по-прежнему не работает, поскольку в cassandra есть ошибка ( CASSANDRA-7910), из-за которой он не возвращает новые столбцы, поскольку сам кэширует подготовленный оператор на своей стороне и не делает его недействительным при изменении схемы. Эта проблема исправлена ​​в 2.1.3 (скоро), возможно, стоит попробовать это с веткой cassandra-2.1 в git, чтобы посмотреть, решит ли это вашу проблему.

Это не ненормальный шаблон для изменения вашей схемы, когда ваше приложение работает, так что это сценарий, который должен работать, но, к сожалению, нет. Я хотел бы посмотреть, есть ли способ представить утверждения в gocql.

Я вижу, что есть stmtsLRU var в cluster.go. Если бы вы могли как-то добраться до этого, вы могли бы сделать недействительными подготовленные заявления. Если нет способа сделать это, было бы неплохо открыть проблему с gocql, так как вы можете заново представлять операторы в других драйверах. Я знаю, что драйвер Java позволяет вам это сделать, но выдает предупреждение. Я полагаю, что между gocql и другими драйверами может быть большая разница в том, что в других драйверах вы явно используете подготовленный объект оператора, где в gocql он обрабатывается для вас автоматически в библиотеке.

С выдающейся ошибкой cassandra, я думаю, вы должны придерживаться не использования подготовленных операторов и вместо этого делать запросы вроде: SELECT * FROM api_counters WHERE date = 'total';

Другие вопросы по тегам