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';
Я получаю правильный полный результат. Итак:
- мог появиться gocql водитель ?
- является ли эта модель полностью глупой ?
Исходит ли это из моей просьбы, которая должна быть иной ?
Мое временное решение состоит в том, чтобы выбрать имена столбцов из таблицы system.schema_columns и строк.Join () все это к моему выбору запрос...
Большое Спасибо за вашу помощь.
2 ответов:
Я не знаком с библиотекой gocql, но похоже, что вы можете столкнуться с комбинацией нерепрезентирующих ваши утверждения и CASSANDRA-7910 .
Всякий раз, когда запрос подготовлен (например, что делается в Select * from _ _ where date in ?), он отправляет запрос Кассандре, которая отвечает метаданными столбцов для этой таблицы, поэтому, когда вы получаете ответ на запрос от Кассандры, вы знаете, какие столбцы доступны для поиска. Похоже, что gocql имеет функция под названием
Automatic query preparation, которая может рассматривать ваш запрос как подготовленный оператор.Когда вы изменяете таблицу, подготовленный оператор не обновляется на стороне клиента, поэтому единственный способ исправить это-повторно подготовить ваш оператор (не уверен, что у вас есть такой уровень управления от gocql). Однако это все еще не работает, так как есть ошибка в cassandra (CASSANDRA-7910), где он не возвращает новые столбцы, так как он сам кэширует подготовленный оператор на это сторона и не делает ее недействительной при изменении схемы. Эта проблема исправлена в 2.1.3 (скоро), возможно, стоит попробовать это против ветви cassandra-2.1 в git, чтобы увидеть, если это решит вашу проблему.
Это не ненормальный шаблон для изменения вашей схемы, когда ваше приложение работает, так что это сценарий, который должен работать, но, к сожалению, не работает. я бы посмотрел, есть ли способ репрепарировать операторы в gocql.
Я вижу, что в кластере есть
stmtsLRUvar.идти. Если бы вы могли каким-то образом добраться до этого, вы могли бы аннулировать подготовленные заявления. Если нет способа сделать это, было бы хорошо, чтобы открыть проблему против gocql, как вы можете reprepare операторы снова в других драйверах. Я знаю, что драйвер java позволяет вам сделать это, но дает вам предупреждение. Я полагаю, что это может быть большой разницей между gocql и другими драйверами в том, что в других драйверах вы явно используете подготовленный объект оператора, где в gocql он обрабатывается автоматически в библиотеке.С выдающейся ошибкой Кассандры, я думаю, вы должны придерживаться не использовать подготовленные заявления и вместо этого делать запросы, такие как:
SELECT * FROM api_counters WHERE date = 'total';
Спасибо Энди за вашу помощь.
Сначала я подумал, что, учитывая то, что вы мне сказали, я бы предпочел иногда делать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 : мой шаблон не был лучшим.
Comments