там сжатый способ получить случайную запись от таблицы SQL-сервера?
Да
SELECT TOP 1 * FROM table ORDER BY NEWID()
Объяснение
А
NEWID()
сгенерирован для каждой строки, и таблица тогда отсортирована по нему. Первая запись возвращается (т.е. запись с "самым низким" GUID).Примечания
GUID сгенерированы как псевдослучайные числа начиная с версии четыре:
UUID версии 4 предназначен для генерации UUID от действительно случайных или псевдослучайных чисел.
алгоритм следующие:
- Набор два старших значащих бита (биты 6 и 7) clock_seq_hi_and_reserved для обнуления и один, соответственно.
- Набор четыре старших значащих бита (биты 12 - 15) time_hi_and_version поля к 4-разрядному номеру версии от Раздела 4.1.3.
- Набор все другие биты к случайным образом (или псевдослучайным образом) выбранные значения.
— А Универсально Уникальный идентификатор (UUID) Пространство имен УРНЫ - RFC 4122
альтернатива
SELECT TOP 1 * FROM table ORDER BY RAND()
не будет работать, как можно было бы думать.RAND()
возвраты одно единственное значение на запрос, таким образом все строки совместно используют то же значение., В то время как значения GUID являются псевдослучайными, Вам будет нужен лучший PRNG для большего количества требовательных приложений.
Типичная производительность составляет меньше чем 10 секунд приблизительно для 1 000 000 строк — конечно, в зависимости от системы. Обратите внимание, что невозможно поразить индекс, таким образом производительность будет относительно ограничена.
Вы можете использовать setattr
(будьте осторожны: не каждая строка допустимое имя атрибута!):
>>> class AllMyFields:
... def __init__(self, dictionary):
... for k, v in dictionary.items():
... setattr(self, k, v)
...
>>> o = AllMyFields({'a': 1, 'b': 2})
>>> o.a
1
Изменить: позвольте мне объяснить разницу между приведенным выше кодом и ответом SilentGhost . Приведенный выше фрагмент кода создает класс, атрибуты экземпляра которого основаны на данном словаре. Код SilentGhost создает класс, атрибуты класса которого основаны на заданном словаре.
В зависимости от вашей конкретной ситуации любое из этих решений может быть более подходящим. Вы просто создаете один или несколько экземпляров класса? Если ответ один, вы также можете полностью пропустить создание объекта и сконструировать только тип (и, таким образом, перейти к ответу SilentGhost).
Использование именованных кортежей (Python 2.6):
>>> from collections import namedtuple
>>> the_dict = {'Field1': 3, 'Field2': 'b', 'foo': 4.9}
>>> fields = ' '.join(the_dict.keys())
>>> AllMyFields = namedtuple('AllMyFields', fields)
>>> instance = AllMyFields(**the_dict)
>>> print instance.Field1, instance.Field2, instance.foo
3 b 4.9
Вы могли создайте подкласс dict
, который позволяет искать атрибуты для ключей:
class AttributeDict(dict):
def __getattr__(self, name):
return self[name]
q = AttributeDict({ 'Field1' : 3000, 'Field2' : 6000, 'RandomField' : 5000 })
print q.Field1
print q.Field2
print q.RandomField
Если вы попытаетесь найти атрибут, который dict
уже имеет (скажем, ключи
или get
), вы получите атрибут класса dict
(метод). Если запрашиваемый ключ не существует в классе dict
, то будет вызван метод __ getattr __
, который выполнит поиск вашего ключа.
>>> q = { 'Field1' : 3000, 'Field2' : 6000, 'RandomField' : 5000 }
>>> q = type('allMyFields', (object,), q)
>>> q.Field1
3000
документы для типа
хорошо объясняют, что здесь происходит (см. Использование в качестве конструктора).
редактировать : в случае, если вам нужны переменные экземпляра, также работает:
>>> a = q() # first instance
>>> a.Field1
3000
>>> a.Field1 = 1
>>> a.Field1
1
>>> q().Field1 # second instance
3000
Вы также можете использовать dict.update
вместо ручного зацикливания элементов
(а если вы зацикливаете, то iteritems
лучше).
class allMyFields(object):
# note: you cannot (and don't have to) use self here
Field1 = None
Field2 = None
def __init__(self, dictionary):
self.__dict__.update(dictionary)
q = { 'Field1' : 3000, 'Field2' : 6000, 'RandomField' : 5000 }
instance = allMyFields(q)
print instance.Field1 # => 3000
print instance.Field2 # => 6000
print instance.RandomField # => 5000
Используйте setattr для изящного способа. Самый простой способ - обновить внутренний словарь экземпляра:
>>> class A(object):
... pass
...
>>> a = A()
>>> a.__dict__.update({"foo": 1, "bar": 2})
>>> a.foo
1
>>> a.bar
2
>>>