Səhifələr

Blogroll

26 December 2017

MongoDB Community Server 3.6.0 versiyasının Centos/Rhel 7.0 üzərinə qurulması və start edilməsi.

MongoDB Community Server 3.6.0 versiyasının Centos/Rhel 7.0  üzərinə qurulması və start edilməsi.
MongoDB cross-platform, ödəniş tələb etməyən, sənəd-yönümlü(document-oriented) məlumatlar bazası proqramıdır. NoSQL database kimi klassifikasiya edilir. Open source proektdir və kodu GNU AGPLv3 lisenziyası ilə yayımlanır (https://github.com/mongodb/mongo). MongoDB kodu əsasən C++ və JavaScript üzərində yazlmışdır.

MongoDB sharding və məlumatların replikasiyası özəlliyinə görə çox müxtəlif sahələrdə istifadəsi mümkündür.
               

Bu məqalənin mövzusu MongoDB – nin qurulması və start edilməsi olduğuna görə onun arxitekturası və ya istifadə sahələri barədə danışılmayacaq.
Bu məqalədə YUM repozitoriyasından istifadə edərək MongoDB paketlərinin qurulmasına baxacağıq.
Yum repozitoriyasından qurulum edə bilmək üçün öncə repo faylını yaratmalıyıq. /etc/yum.repos.d folderində .repo sonluqlu yeni bir fayl yaradırıq və aşağıdakı məlumatları əlavə edirik.


[mongodb36]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/redhat/$releasever/mongodb-org/3.6/x86_64/
gpgcheck=1
enabled=1
gpgkey=https://www.mongodb.org/static/pgp/server-3.6.asc

Digər Linux distro-ları və ya MongoDB-nin əvvəlki versiyalarını qurmaq istəyirsinizsə aşağıdakı linkdən istifadə edərək sizə uyğun repo-nu qura bilərsiniz.


Nümunə üçün MongoDB-nin 3.6 deyil 3.4 versiyası üçün repo faylı aşağıdakı kimi olacaq.

[mongodb34]
name=MongoDB 3.4 Repository
baseurl=https://repo.mongodb.org/yum/redhat/$releasever/mongodb-org/3.4/x86_64/
gpgcheck=0
enabled=1

Yaratdığımız repo fayllarının işlək olduğunu yoxlamaq üçün yum repolist əmrindən istifadə edək. Nəticəniz aşağıdakı kimidirsə repo-lar işləkdir.


MongoDB-nin 3.6 versiyası SSL dəstəyi ilə compile olduğuna əgər sisteminizdə OpenSLL qurulu deyilsə qurulmasına ehtiyac vardır. Yum install openssl əmri ilə bunu edə bilərsiniz.
MongoDB-nin qurulması üçün yum install mongodb-org əmrindən istifadə edəcəyik. Bu komanda ilə aşağıdakı paketlər qurulacaq.


Baxmayaraq ki, bizim repo-larda həm 3.4 həm də 3.6 versiyaları mövcuddur, yum susmaya görə ən yeni versiyanın yüklənməsini təklif edəcək. Hər hansı spesifik paket və ya versiyanın qurulmasını istəyirsinizsə bu zaman bunu qeyd etməyiniz lazımdır.

yum install mongodb-org-3.4.0


RedHat və Centos – da Selinux istifadə edirsinizsə MongoDB-nin işlədiyi port-un Selinux port context-ni dəyişməlisiniz. Getenforce əmri ilə Selinux-un aktiv olub – olmamasını yoxlaya bilərsiniz (Enforcing-aktivdir, Permissive və ya Disabled – aktiv deyil). Əgər fərqli dəyər verilməyibsə bu susmaya görə 27017 portudur. /etc/mongod.conf faylında bu dəyər net bölməsinin altında qeyd edilməlidir.


Hansı port istifadə edilməsindən asılı olaraq selinux əmri aşağıdakı kimi olacaq. Əgər Selinux Permissive və Disabled modundadırsa bu əməliyyatı etməyə ehtiyac yoxdur.

semanage port -a -t mongod_port_t -p tcp 27017

MongoDB servisini start etməzdən öncə /etc/mongod.conf faylına nəzər yetirək. Hal – hazırda bu faylda servisin start edilməsi üçün gərəkli olan ilkin parametrlər qeyd edilib. Bunlardan bizə maraqlı olan storage systemLog bölmələridir. Storage bölməsində MongoDB data fayllarının hansı qovluqda yerləşəcəyi qeyd edilir. Server yükləndikdə susmaya görə bu /var/lib/mongo qovluğudur. İstəyinizə və tələblərinizə uyğun olaraq dəyişdirilə bilər. Qovluq dəyişdirilərsə yeni dəyər /etc/mongod.conf faylında qeyd edilir və əgər Selinux aktivdirsə uyğun context verilir. Nümunə üçün əgər data qovluğunu /data ilə əvəzləyəriksə aşağıdakı dəyişikliklər edilməlidir.

semanage fcontext -a -t mongod_var_lib_t "/data(/.*)?"



Config faylına müvafiq dəyişikliklər etdikdən sonra mongod servisini start edə bilərik.

systemctl start mongod


Data fayllarımızın yerləşdiyi qovluğu yoxladıqda faylların yarandığını görə bilərik.


Serverimiz start oldu və biz artıq mongo əmrini işə salaraq ona bağlanaraq istifadə edə bilərik.





MongoDB və ümumiyyətlə NoSQL mənim üçün də yeni mövzu olduğuna görə təklif və düzəlişlərinizi şərhlər bölməsində qeyd edə bilərsiniz. 

23 August 2017

Rename SQL Server hostname

To rename a computer that hosts a stand-alone instance of SQL Server

  • For a renamed computer that hosts a default instance of SQL Server, run the following procedures:
    sp_dropserver ;  
    GO  
    sp_addserver , local;  
    GO  
    
    Restart the instance of SQL Server.
  • For a renamed computer that hosts a named instance of SQL Server, run the following procedures:
    sp_dropserver ;  
    GO  
    sp_addserver , local;  
    GO  
    
    Restart the instance of SQL Server.
  • +


08 August 2017

What is the use of the yield keyword in Python? What does it do?


Sual
For example, I'm trying to understand this code1:
def _get_child_candidates(self, distance, min_dist, max_dist):
    if self._leftchild and distance - max_dist < self._median:
        yield self._leftchild
    if self._rightchild and distance + max_dist >= self._median:
        yield self._rightchild  
And this is the caller:
result, candidates = list(), [self]
while candidates:
    node = candidates.pop()
    distance = node._get_dist(obj)
    if distance <= max_dist and distance >= min_dist:
        result.extend(node._values)
    candidates.extend(node._get_child_candidates(distance, min_dist, max_dist))
return result
What happens when the method _get_child_candidates is called? Is a list returned? A single element? Is it called again? When will subsequent calls stop?

Cavab
To understand what yield does, you must understand what generators are. And before generators come iterables.

Iterables

When you create a list, you can read its items one by one. Reading its items one by one is called iteration:
>>> mylist = [1, 2, 3]
>>> for i in mylist:
...    print(i)
1
2
3
mylist is an iterable. When you use a list comprehension, you create a list, and so an iterable:
>>> mylist = [x*x for x in range(3)]
>>> for i in mylist:
...    print(i)
0
1
4
Everything you can use "for... in..." on is an iterable; listsstrings, files...
These iterables are handy because you can read them as much as you wish, but you store all the values in memory and this is not always what you want when you have a lot of values.

Generators

Generators are iterators, but you can only iterate over them once. It's because they do not store all the values in memory, they generate the values on the fly:
>>> mygenerator = (x*x for x in range(3))
>>> for i in mygenerator:
...    print(i)
0
1
4
It is just the same except you used () instead of []. BUT, you cannot perform for i in mygenerator a second time since generators can only be used once: they calculate 0, then forget about it and calculate 1, and end calculating 4, one by one.

Yield

yield is a keyword that is used like return, except the function will return a generator.
>>> def createGenerator():
...    mylist = range(3)
...    for i in mylist:
...        yield i*i
...
>>> mygenerator = createGenerator() # create a generator
>>> print(mygenerator) # mygenerator is an object!
<generator object createGenerator at 0xb7555c34>
>>> for i in mygenerator:
...     print(i)
0
1
4
Here it's a useless example, but it's handy when you know your function will return a huge set of values that you will only need to read once.
To master yield, you must understand that when you call the function, the code you have written in the function body does not run. The function only returns the generator object, this is a bit tricky :-)
Then, your code will be run each time the for uses the generator.
Now the hard part:
The first time the for calls the generator object created from your function, it will run the code in your function from the beginning until it hits yield, then it'll return the first value of the loop. Then, each other call will run the loop you have written in the function one more time, and return the next value, until there is no value to return.
The generator is considered empty once the function runs but does not hit yield anymore. It can be because the loop had come to an end, or because you do not satisfy an "if/else" anymore.

Your code explained

Generator:
# Here you create the method of the node object that will return the generator
def _get_child_candidates(self, distance, min_dist, max_dist):

    # Here is the code that will be called each time you use the generator object:

    # If there is still a child of the node object on its left
    # AND if distance is ok, return the next child
    if self._leftchild and distance - max_dist < self._median:
        yield self._leftchild

    # If there is still a child of the node object on its right
    # AND if distance is ok, return the next child
    if self._rightchild and distance + max_dist >= self._median:
        yield self._rightchild

    # If the function arrives here, the generator will be considered empty
    # there is no more than two values: the left and the right children
Caller:
# Create an empty list and a list with the current object reference
result, candidates = list(), [self]

# Loop on candidates (they contain only one element at the beginning)
while candidates:

    # Get the last candidate and remove it from the list
    node = candidates.pop()

    # Get the distance between obj and the candidate
    distance = node._get_dist(obj)

    # If distance is ok, then you can fill the result
    if distance <= max_dist and distance >= min_dist:
        result.extend(node._values)

    # Add the children of the candidate in the candidates list
    # so the loop will keep running until it will have looked
    # at all the children of the children of the children, etc. of the candidate
    candidates.extend(node._get_child_candidates(distance, min_dist, max_dist))

return result
This code contains several smart parts:
  • The loop iterates on a list but the list expands while the loop is being iterated :-) It's a concise way to go through all these nested data even if it's a bit dangerous since you can end up with an infinite loop. In this case, candidates.extend(node._get_child_candidates(distance, min_dist, max_dist)) exhausts all the values of the generator, but while keeps creating new generator objects which will produce different values from the previous ones since it's not applied on the same node.
  • The extend() method is a list object method that expects an iterable and adds its values to the list.
Usually we pass a list to it:
>>> a = [1, 2]
>>> b = [3, 4]
>>> a.extend(b)
>>> print(a)
[1, 2, 3, 4]
But in your code it gets a generator, which is good because:
  1. You don't need to read the values twice.
  2. You may have a lot of children and you don't want them all stored in memory.
And it works because Python does not care if the argument of a method is a list or not. Python expects iterables so it will work with strings, lists, tuples and generators! This is called duck typing and is one of the reason why Python is so cool. But this is another story, for another question...
You can stop here, or read a little bit to see an advanced use of a generator:

Controlling a generator exhaustion

>>> class Bank(): # let's create a bank, building ATMs
...    crisis = False
...    def create_atm(self):
...        while not self.crisis:
...            yield "$100"
>>> hsbc = Bank() # when everything's ok the ATM gives you as much as you want
>>> corner_street_atm = hsbc.create_atm()
>>> print(corner_street_atm.next())
$100
>>> print(corner_street_atm.next())
$100
>>> print([corner_street_atm.next() for cash in range(5)])
['$100', '$100', '$100', '$100', '$100']
>>> hsbc.crisis = True # crisis is coming, no more money!
>>> print(corner_street_atm.next())
<type 'exceptions.StopIteration'>
>>> wall_street_atm = hsbc.create_atm() # it's even true for new ATMs
>>> print(wall_street_atm.next())
<type 'exceptions.StopIteration'>
>>> hsbc.crisis = False # trouble is, even post-crisis the ATM remains empty
>>> print(corner_street_atm.next())
<type 'exceptions.StopIteration'>
>>> brand_new_atm = hsbc.create_atm() # build a new one to get back in business
>>> for cash in brand_new_atm:
...    print cash
$100
$100
$100
$100
$100
$100
$100
$100
$100
...
It can be useful for various things like controlling access to a resource.

Itertools, your best friend

The itertools module contains special functions to manipulate iterables. Ever wish to duplicate a generator? Chain two generators? Group values in a nested list with a one liner? Map / Zipwithout creating another list?
Then just import itertools.
An example? Let's see the possible orders of arrival for a 4 horse race:
>>> horses = [1, 2, 3, 4]
>>> races = itertools.permutations(horses)
>>> print(races)
<itertools.permutations object at 0xb754f1dc>
>>> print(list(itertools.permutations(horses)))
[(1, 2, 3, 4),
 (1, 2, 4, 3),
 (1, 3, 2, 4),
 (1, 3, 4, 2),
 (1, 4, 2, 3),
 (1, 4, 3, 2),
 (2, 1, 3, 4),
 (2, 1, 4, 3),
 (2, 3, 1, 4),
 (2, 3, 4, 1),
 (2, 4, 1, 3),
 (2, 4, 3, 1),
 (3, 1, 2, 4),
 (3, 1, 4, 2),
 (3, 2, 1, 4),
 (3, 2, 4, 1),
 (3, 4, 1, 2),
 (3, 4, 2, 1),
 (4, 1, 2, 3),
 (4, 1, 3, 2),
 (4, 2, 1, 3),
 (4, 2, 3, 1),
 (4, 3, 1, 2),
 (4, 3, 2, 1)]

Understanding the inner mechanisms of iteration

Iteration is a process implying iterables (implementing the __iter__() method) and iterators (implementing the __next__() method). Iterables are any objects you can get an iterator from. Iterators are objects that let you iterate on iterables.
Sual və cavabın orijinal linki.