How to use ARRAY of INET in flask-sqlalchemy? - postgresql

I have a user model with array of ips field in my flask application. I want to use postgresql array of inet type:
from flask.ext.sqlalchemy import SQLAlchemy
from sqlalchemy.dialects.postgresql import ARRAY, INET, Integer, Unicode, Column
db = SQLAlchemy()
class User(db.Model):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
login = Column(Unicode(15))
password = Column(Unicode(34))
name = Column(Unicode(100))
permitted_ips = Column(ARRAY(INET))
But when i make query i get bad answer:
user = User.query.get(84)
print user.permitted_ips
#['{', '1', '7', '2', '.', '2', '0', '.', '2', '5', '.', '2', ',', '1', '7', '2', '.', '2', '0', '.', '2', '5', '.', '3', '}']
instead of ['172.20.25.2', '172.20.25.3']. Current version of sqlalchemy is 0.9.10. I tried the latest one but result was the same. Is it possible to fix that?

I found that Arrays are not parsed automatically so you need to create a generic type caster with psycopg2 library.
# needed imports
from psycopg2 import STRING
from psycopg2.extensions import register_type, new_array_type
Registering the array type, it will be done one time.
# to see the oid of inet. As pointed out by #univerio the oid should never
# change, so you don't need to fetch it every time your app starts.
tp = db.engine.execute("select typarray from pg_type where typname = 'inet'")
print(tp.fetchone())
# (1041,)
# registering the array type
register_type(new_array_type((1041,), 'INET[]', STRING))
Now you can fetch the array and it will be parsed properly.
# fetch data
ips = db.engine.execute("select permitted_ips from users where id = 1")
print(ips.fetchone()[0])
# ['172.20.25.2', '172.20.25.3'].

Related

how to convert numbers from one language to english or forcing the user to write in english only?

I would like to convert Arabic numbers into english or force the user to enter english numbers only, so how to do so?
i.e 123 = ١٢٣ and so on.
For converting numbers you can simply write a function like this:
Map persianNumberMap = {
'۰': '0',
'۱': '1',
'۲': '2',
'۳': '3',
'۴': '4',
'۵': '5',
'۶': '6',
'۷': '7',
'۸': '8',
'۹': '9'
};
String convertPersianNumberToEnglish(String number) {
String converted = number;
persianNumberMap.forEach((key, value) => converted.replaceAll(key, value));
return converted;
}
But you can also use FilteringTextInputFormatter to restrict inputs of a TextField:
TextField(inputFormatters: [
FilteringTextInputFormatter.allow(RegExp("[0-9]")),
])
This TextField will only accept English number characters.

I am getting an index out of range error

My function takes a table of the form dictionary and returns the table after applying the query which the person asked. I have several other methods but I am having trouble with the equal condition method . This is what I've tried.
class Table():
def where_con(self,table,conditions):
for condition in conditions:
if ('='in condition):
print(table.get_dict())
print(condition)
self = table.equal_condition(table,condition)
return(self)
elif('>'in condition):
new_table = table.greater_condition(table, condition)
return(self)
def equal_condition(self,table,condition):
'''(Table, string) -> Table
This Function takes in a table and a condition and applies the
condition and returns a new table with the condition applied
REQ: Table must have the contents of the condition
REQ: The condition must have proper syntax
REQ: The condition must contain the equal sign in string form
'''
number_rows = table.num_rows()
print(number_rows)
dictionary = table.get_dict()
print(dictionary)
condition = condition.split('=')
print(condition)
#new_table = Table()
# Adding Coloums Name in Self
for col in dictionary:
self.add_column({col: []})
# If the Second part is a string
if ("'" in condition[1]):
condition[1] = condition[1].strip("'")
i=0
while(i<number_rows):
print(i)
i=i+1
if (dictionary[condition[0]][i] == condition[1]):
for key in self.get_dict():
self = self.update_column(key,dictionary[key][i])
#i=i+1
else:
i=0
while(i<number_rows):
print(i)
if (dictionary[condition[0]][i] == dictionary[condition[1]][i]):
for key in self.get_dict():
self.update_column(key,dictionary[key][i])
i=i+1
return self
So when I give an input as
>>>a = Table()
>>>a.set_dict({'w.critic_rating': ['5', '5', '5', '5'], 'o.for': ['Directing', 'Acting', 'Directing', 'Acting'], 'w.title': ['Titanic', 'Titanic', 'Avatar', 'Avatar'], 'o.title': ['Avatar', 'Titanic', 'Avatar', 'Titanic'], 'w w.your_rating': ['4.5', '4.5', '5', '5'], 'w.average_rating': ['4.75', '4.75', '5', '5']})
>>>d = Table()
>>>f = where_con(a,"w.title=o.title")
4
{'o.for': ['Directing', 'Acting', 'Directing', 'Acting'], 'o.title': ['Avatar', 'Titanic', 'Avatar', 'Titanic'], 'w.critic_rating': ['5', '5', '5', '5'], 'w.your_rating': ['4.5', '4.5', '5', '5'], 'w.average_rating': ['4.75', '4.75', '5', '5'], 'w.title': ['Titanic', 'Titanic', 'Avatar', 'Avatar']}
['w.title', 'o.title']
0
Traceback (most recent call last):
Python Shell, prompt 2, line 1
File "C:\Users\Abhinav\Desktop\MAde_answer\database.py", line 205, in <module>
if (dictionary[condition[0]][i] == dictionary[condition[1]][i]):
builtins.IndexError: list index out of range
Why is this happening and how can I fix it . Any help is appreciated.

Standard or convention for DateTime to [A-Z] string conversion?

I like to use DateTime.UtcNow.ToString("yyyyMMddHHmmss") as a unique-enough salt for padding instead of a random string or GUID in tests for easier debugging and sorting. However I can't use it where validation only allows alpha character strings, e.g. a name (where 'Falsehoods Programmers Believe About Names' is ignored).
Is there a standard or a convention to encode a timestamp as a [A-Z]+ string? Preferably something more efficient than roman numerals but still human readable, i.e. not a base64-like lookup-table-based variant but a logic-based one.
Not that I know of, but if you treat A as 0 and J as 9 you can simply replace all numbers from the yyyyMMddHHmmss string.
I ended up with a lookup using a mix of leet speak and calculator spelling forgoing sorting in lieu of readability.
http://www.wikihow.com/Sample/1337-Cheat-Sheet
http://www.wikihow.com/Sample/Calculator-Letter-List
http://www.inversoft.com/blog/2013/08/28/profanity-filtering-101-character-replacements-leet-speak/
var map = new Dictionary<char, char>
{
{ '0', 'O' },
{ '1', 'I' },
{ '2', 'Z' },
{ '3', 'E' },
{ '4', 'A' },
{ '5', 'S' },
{ '6', 'G' },
{ '7', 'T' },
{ '8', 'B' },
{ '9', 'P' }
};
return string.Concat(value.Select(c => map[c]));

Saving postgresql array datatype in cakephp ignores all array datatype fields

Saving model data fails to insert any of array datatype fields. Data array to store.
array(
'catalog_id' => '14',
'foreign_model[1]' => 'Catalog',
'foreign_model_key[1]' => (int) 3,
'foreign_key[1]' => '4',
'name' => 'T580.26',
'integer[1]' => '44000',
'integer[2]' => '3'
'amount[1]' => '140000';
)
Stored are only catalog_id and name values.
What I have tried so far.
$this->Catalog->save($data, array_keys($data));
and
$this->Catalog->whitelist = array_keys($data);
$this->Catalog->save($data);
Any ideas what else can be done?
Array is a data type that is not supported by CakePHP's ORM.
See https://github.com/cakephp/cakephp/blob/master/lib/Cake/Model/Datasource/Database/Postgres.php#L53
You can extend the Postgres datasource and add it.

How to create WHERE IN clause with Zend_Db_Select

So I am trying to accomplish something like this:
SELECT * FROM table WHERE status_id IN (1,3,4);
using Zend_Db_Select... can't find how to do it :( Is it at all possible?
you can also use it like this:
$data = array(1,3,4);
$select->where('status_id IN(?)', $data);
you dont need to implode array, and it's safer
The first answer probably works in ZF1 but it doesn't work in Zend Framework 2:
$data = array(1,3,4);
$select->where('status_id IN(?)', $data);
In case the Zend Framework2 I found out that you have to use:
$data = array(1,3,4);
$select->where(array('status_id' => $data));
Result:
WHERE `status_id` IN ('1', '3', '4')
I couldn't find this documented anywhere! ZF documentation is generally sub-optimal.
apparently it is super simple... stupid me:
$select->where('status_id IN(1,3,4)');
:(
We can use Zend\Db\Sql\Predicate\In with Zend\Db\Sql\Where to make a where in query inside a model.
$this->status_ids = array(1,3,4);
// select attributes from db by where in
$result = $this->select(function (Select $select) {
$predicate = new In();
$select->where(
$predicate->setValueSet($this->status_ids)
->setIdentifier('status_id')
);
})->toArray();
$completionNo = implode(",",$data);
$db = Zend_Db_Table_Abstract::getDefaultAdapter();
$select = $db->select()->from(array("p"=>PREFIX . "property_master"),array('id','completion_no','total_carpet_area'))->where("p.completion_no IN (?)", $completionNo);
This solution works well with zf2
$ids = array('1', '2', '3', '4', '5', '6', '7', '8');
$select->where(array("app_post_id"=> $ids));
or
$ids = array('1', '2', '3', '4', '5', '6', '7', '8');
$sql = new Sql($this->adapter);
$select = $sql->select();
$select->from('app_post_comments');
$select->where(array("app_post_id"=> $ids));
// echo $select->getSqlString($this->adapter->getPlatform());
// exit;
$statement = $sql->prepareStatementForSqlObject($select);
$result = $statement->execute();
$resultSet = new ResultSet();
$resultSet->initialize($result);
$resultSet->buffer()->toArray();
echo '<pre>';
print_r($resultSet);
exit;
return $resultSet;